定制 tiime/api-deprecation-bundle 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tiime/api-deprecation-bundle

Composer 安装命令:

composer require tiime/api-deprecation-bundle

包简介

Symfony bundle for managing API endpoint deprecation with Deprecation, Sunset and Link HTTP headers, including brownout support

README 文档

README

logo Tiime
API Deprecation Bundle

Symfony bundle for managing API endpoint deprecation via standard HTTP headers, with brownout support (planned interruptions).

HTTP Headers

Header RFC Description
Deprecation RFC 9745 Indicates when the endpoint was deprecated
Sunset RFC 8594 Indicates when the endpoint will be removed
Link RFC 9745 §3 Points to deprecation documentation (rel="deprecation")
Retry-After RFC 7231 §7.1.3 Seconds until brownout window ends (brownout 410 responses only)

Installation

composer require tiime/api-deprecation-bundle

Configuration

# config/packages/api_deprecation.yaml
api_deprecation:
    enabled: true
    gone_after_sunset: true          # return 410 Gone after the sunset date
    brownout_strategies:
        progressive:
            phases:
                - starts_before: '30 days'   # activates 30 days before sunset
                  cron: '0 10 * * 1'         # every Monday at 10am
                  duration: 15               # for 15 minutes
                - starts_before: '14 days'   # activates 14 days before sunset
                  cron: '0 */4 * * *'        # every 4 hours
                  duration: 30               # for 30 minutes
                - starts_before: '7 days'    # activates 7 days before sunset
                  cron: '0 * * * *'          # every hour
                  duration: 45               # for 45 minutes

Usage

Simple deprecation

Add the Deprecation header to an endpoint:

use Tiime\ApiDeprecationBundle\Attribute\ApiDeprecated;

class UserController
{
    #[ApiDeprecated(since: '2024-06-01')]
    public function list(): Response
    {
        // ...
    }
}

Response:

HTTP/1.1 200 OK
Deprecation: @1717200000

With sunset and link to deprecation documentation

#[ApiDeprecated(
    since: '2024-06-01',
    sunset: '2025-01-01',
    link: 'https://docs.example.com/api/v1/users-deprecation',
)]
public function list(): Response
{
    // ...
}

Response:

HTTP/1.1 200 OK
Deprecation: @1717200000
Sunset: Wed, 01 Jan 2025 00:00:00 GMT
Link: <https://docs.example.com/api/v1/users-deprecation>; rel="deprecation"; type="text/html"

On an entire controller

The attribute can be placed on the class. Methods without their own attribute inherit from the class:

#[ApiDeprecated(since: '2024-06-01', sunset: '2025-06-01')]
class LegacyUserController
{
    public function list(): Response { /* ... */ }
    public function show(): Response { /* ... */ }
}

A method-level attribute always takes priority over the class-level one.

Brownouts

Brownouts are planned, temporary interruptions of a deprecated endpoint. During a brownout window, the endpoint returns 410 Gone instead of the normal response. This forces API consumers to migrate to the new endpoint.

A brownout strategy is composed of phases. Each phase defines a cron expression, a duration, and how long before sunset it activates. This allows you to progressively increase pressure on consumers as the sunset date approaches.

Defining a strategy

api_deprecation:
    brownout_strategies:
        progressive:
            phases:
                - starts_before: '30 days'
                  cron: '0 10 * * 1'      # Monday at 10am
                  duration: 15
                - starts_before: '7 days'
                  cron: '0 */2 * * *'     # every 2 hours
                  duration: 30

Referencing the strategy in the attribute

The brownout parameter references the name of a strategy defined in the configuration. A sunset date is required when a brownout is configured (phases activate relative to that date).

#[ApiDeprecated(
    since: '2024-06-01',
    sunset: '2025-01-01',
    link: 'https://docs.example.com/api/v1/users-deprecation',
    brownout: 'progressive',
)]
public function list(): Response
{
    // ...
}

Behavior during a brownout

During the brownout window, the response is:

HTTP/1.1 410 Gone
Retry-After: 540
Deprecation: @1717200000
Sunset: Wed, 01 Jan 2025 00:00:00 GMT
Link: <https://docs.example.com/api/v1/users-deprecation>; rel="deprecation"; type="text/html"

This endpoint is deprecated and currently unavailable (brownout).

Outside the window, the endpoint works normally with deprecation headers.

Behavior after sunset

If gone_after_sunset is enabled (default), the endpoint permanently returns 410 Gone once the sunset date has passed.

Customizing the error response

Two Symfony events are dispatched before the default 410 Gone response is returned:

  • ApiSunsetEvent — dispatched when the sunset date has passed
  • ApiBrownoutEvent — dispatched during a brownout window

An event listener can call $event->setResponse() to replace the default 410 with a custom response. Both events expose the ApiDeprecated attribute and the deprecation headers that will be added to the response.

Example: returning a Problem Details response (RFC 9457)

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\JsonResponse;
use Tiime\ApiDeprecationBundle\Event\ApiBrownoutEvent;
use Tiime\ApiDeprecationBundle\Event\ApiSunsetEvent;

#[AsEventListener]
final class DeprecationProblemDetailsListener
{
    public function __invoke(ApiSunsetEvent|ApiBrownoutEvent $event): void
    {
        $response = new JsonResponse([
            'type' => 'https://docs.example.com/errors/gone',
            'title' => 'Gone',
            'status' => 410,
            'detail' => sprintf(
                'This endpoint was deprecated on %s and is no longer available.',
                $event->attribute->since,
            ),
        ], 410, ['Content-Type' => 'application/problem+json']);

        $event->setResponse($response);
    }
}

The $event->headers array contains the computed deprecation headers (Deprecation, Sunset, Link, Retry-After) — they are automatically added to whatever response is returned.

If no listener sets a response, the default 410 Gone with a plain-text body is returned (backward compatible).

Attribute parameters

Parameter Type Default Description
since string|null null Deprecation date (ISO 8601)
sunset string|null null Removal date (ISO 8601)
link string|null null URL to deprecation documentation (RFC 9745 §3)
brownout string|null null Name of a brownout strategy defined in the configuration

Requirements

  • PHP >= 8.3
  • Symfony 6.4 or 7.x or 8.x

Tests

docker compose run --rm php vendor/bin/phpunit

License

MIT

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 4
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-13

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固