← API

API FEATURE

Sunset Version

Deprecated API versions should still be understandable: the response body is intact, but the headers clearly say the contract is on the way out.

Feature Guide

A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.

What this does

The sunset-version page turns a deprecated API route into a documented lifecycle example instead of dropping users into raw JSON with no framing.

How it works

The handler precomputes the same collection payload the API would emit and surfaces the version headers alongside the body inside a feature page. That keeps the live response visible while still explaining why Deprecation and Sunset are present.

Why it matters

Versioning is not just a payload problem. Teams need to see the response contract, lifecycle headers, and migration signal together in one place.

Key concepts

Deprecation
HTTP response header advertising that a version is already on the retirement path.
Sunset
HTTP response header announcing the target retirement date for an API version.
X-Api-Version
Stable response header exposing the semantic version metadata for the current route.

Version Lifecycle

Deprecated collection endpoint with explicit retirement headers

The page keeps the actual JSON payload visible, but the important story is in the lifecycle metadata wrapped around it.

Route GET /demo/api/sunset-version
Response 200 application/json
CLI curl -i -H "Accept: application/json" "http://localhost:9502/demo/api/sunset-version"
Header Value
Content-Type application/json
X-Api-Version 0.9.0
Deprecation 2025-06-01
Sunset 2026-06-01

Deprecated version payload

{
    "data": [
        {
            "slug": "air-purifier",
            "name": "Air Purifier",
            "price": 149.99,
            "description": "HEPA filter, 3 fan speeds, night mode.",
            "status": "active",
            "category": {
                "slug": "home",
                "name": "Home"
            },
            "rating": 3.3,
            "links": {
                "self": "/demo/api/v1/products/air-purifier",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "domain-driven-design",
            "name": "Domain-Driven Design",
            "price": 54.99,
            "description": "Eric Evans' seminal work on tackling complexity in software.",
            "status": "active",
            "category": {
                "slug": "books",
                "name": "Books"
            },
            "rating": 2.8,
            "links": {
                "self": "/demo/api/v1/products/domain-driven-design",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "ergonomic-chair",
            "name": "Ergonomic Chair",
            "price": 299.99,
            "description": "Mesh back, adjustable lumbar, 4D armrests.",
            "status": "active",
            "category": {
                "slug": "home",
                "name": "Home"
            },
            "rating": 2.8,
            "links": {
                "self": "/demo/api/v1/products/ergonomic-chair",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "foam-roller",
            "name": "Foam Roller",
            "price": 29.99,
            "description": "High-density EVA foam, 45 cm, textured surface.",
            "status": "active",
            "category": {
                "slug": "sports",
                "name": "Sports"
            },
            "rating": 3.5,
            "links": {
                "self": "/demo/api/v1/products/foam-roller",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "head-first-design-patterns",
            "name": "Head First Design Patterns",
            "price": 49.99,
            "description": "A brain-friendly guide to design patterns.",
            "status": "active",
            "category": {
                "slug": "books",
                "name": "Books"
            },
            "rating": 3.3,
            "links": {
                "self": "/demo/api/v1/products/head-first-design-patterns",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "linen-shirt",
            "name": "Linen Shirt",
            "price": 54.99,
            "description": "Breathable linen, relaxed fit, button-down collar.",
            "status": "active",
            "category": {
                "slug": "clothing",
                "name": "Clothing"
            },
            "rating": 2.5,
            "links": {
                "self": "/demo/api/v1/products/linen-shirt",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "portable-monitor",
            "name": "Portable Monitor",
            "price": 249.99,
            "description": "15.6\" IPS display, USB-C powered, 1080p.",
            "status": "active",
            "category": {
                "slug": "electronics",
                "name": "Electronics"
            },
            "rating": 3,
            "links": {
                "self": "/demo/api/v1/products/portable-monitor",
                "collection": "/demo/api/v1/products"
            }
        },
        {
            "slug": "power-bank",
            "name": "Power Bank",
            "price": 59.99,
            "description": "20000mAh, dual USB-C, fast charging.",
            "status": "active",
            "category": {
                "slug": "electronics",
                "name": "Electronics"
            },
            "rating": 3,
            "links": {
                "self": "/demo/api/v1/products/power-bank",
                "collection": "/demo/api/v1/products"
            }
        }
    ],
    "meta": {
        "representation": "json",
        "profile": "standard",
        "fields": [],
        "expand": [],
        "page": 1,
        "limit": 8,
        "total": 12,
        "query": null,
        "filters": []
    },
    "links": {
        "self": "/demo/api/v1/products"
    }
}
#[ApiVersion] Deprecation Sunset X-Api-Version

Verified against Semitexa Ultimate 2026.09.19.1020

Sunset Version

Deprecated API versions should still be understandable: the response body is intact, but the headers clearly say the contract is on the way out.

How it works

Setting the lifecycle to deprecated on #[ApiVersion] makes the framework emit three additional headers alongside the normal X-Api-Version: Deprecation carries the date the contract entered retirement, and Sunset carries the date it will stop being served. The response body is unchanged — the route still resolves successfully.

Why this matters

Retirement notice should be explicit without immediately breaking integrations. X-Api-Version makes the serving contract version visible in every response, Deprecation tells consumers when to start migrating, and Sunset gives them a hard deadline. Observability and support workflows need a precise contract version, not guesses from the URL path alone.

© Edsger W. Dijkstra: "Simplicity is prerequisite for reliability."

Sunset Version Handler Application entry point
<?phpdeclare(strict_types=1);namespace App\Application\Handler\Api;use App\Application\Payload\Api\ProductListV0Payload;use App\Application\Resource\Api\ProductListV0Resource;use App\Domain\Api\ProductApiReaderInterface;use Semitexa\Core\Attribute\AsPayloadHandler;use Semitexa\Core\Attribute\InjectAsReadonly;use Semitexa\Core\Contract\TypedHandlerInterface;#[AsPayloadHandler(payload: ProductListV0Payload::class, resource: ProductListV0Resource::class)]final class ProductListV0Handler implements TypedHandlerInterface{    #[InjectAsReadonly]    protected ProductApiReaderInterface $reader;    public function handle(ProductListV0Payload $payload, ProductListV0Resource $resource): ProductListV0Resource    {        return $resource->fromProducts($this->reader->listLegacyVersion());    }}

Lifecycle Notes

What this endpoint is proving

Concern Behavior Why it matters
Client warning The body still resolves successfully, but `Deprecation` and `Sunset` tell consumers to leave the route. Retirement notice should be explicit without immediately breaking integrations.
Version traceability `X-Api-Version: 0.9.0` makes the serving contract visible in every response. Observability and support workflows need a precise contract version, not guesses from the URL alone.

How it works

The handler precomputes the same collection payload the API would emit and surfaces the version headers alongside the body inside a feature page. That keeps the live response visible while still explaining why Deprecation and Sunset are present.

Why it matters

Versioning is not just a payload problem. Teams need to see the response contract, lifecycle headers, and migration signal together in one place.

Key concepts

Deprecation
HTTP response header advertising that a version is already on the retirement path.
Sunset
HTTP response header announcing the target retirement date for an API version.
X-Api-Version
Stable response header exposing the semantic version metadata for the current route.

Support Semitexa
Built for developers who prefer control over magic. Your support helps keep it fast, open, and evolving.

Donate via PayPal