feat(api): allow versioned route sunset replacements

This commit is contained in:
Virgil 2026-04-01 21:50:30 +00:00
parent b2116cc896
commit 691ef936d4
3 changed files with 49 additions and 4 deletions

View file

@ -145,7 +145,7 @@ VersionedRoutes::versions([1, 2], function () {
// Deprecated version with sunset
VersionedRoutes::v1()
->deprecated('2025-06-01')
->deprecated('2025-06-01', '/api/v2/new-endpoint')
->routes(function () {
Route::get('/legacy', LegacyController::class);
});

View file

@ -72,7 +72,7 @@ use Illuminate\Support\Facades\Route;
*
* ```php
* VersionedRoutes::v1()
* ->deprecated('2025-06-01')
* ->deprecated('2025-06-01', '/api/v2/new-endpoint')
* ->routes(function () {
* Route::get('/legacy', ...);
* });
@ -86,6 +86,11 @@ class VersionedRoutes
protected ?string $sunsetDate = null;
/**
* @var string|null
*/
protected ?string $replacement = null;
protected bool $isDeprecated = false;
/**
@ -178,11 +183,13 @@ class VersionedRoutes
* Mark this version as deprecated.
*
* @param string|null $sunsetDate Optional sunset date (YYYY-MM-DD or RFC7231 format)
* @param string|null $replacement Optional replacement endpoint URL
*/
public function deprecated(?string $sunsetDate = null): static
public function deprecated(?string $sunsetDate = null, ?string $replacement = null): static
{
$this->isDeprecated = true;
$this->sunsetDate = $sunsetDate;
$this->replacement = $replacement;
return $this;
}
@ -240,7 +247,11 @@ class VersionedRoutes
$middleware = ["api.version:{$this->version}"];
if ($this->isDeprecated && $this->sunsetDate) {
$middleware[] = "api.sunset:{$this->sunsetDate}";
if ($this->replacement !== null && $this->replacement !== '') {
$middleware[] = "api.sunset:{$this->sunsetDate},{$this->replacement}";
} else {
$middleware[] = "api.sunset:{$this->sunsetDate}";
}
}
return array_merge($middleware, $this->middleware);

View file

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
use Core\Front\Api\VersionedRoutes;
it('passes a replacement url through deprecated versioned routes', function () {
$routes = new class (2) extends VersionedRoutes {
public function attributes(): array
{
return $this->buildRouteAttributes();
}
};
$attributes = $routes->deprecated('2025-06-01', '/api/v3/users')->attributes();
expect($attributes)->toHaveKey('middleware');
expect($attributes['middleware'])->toContain('api.version:2');
expect($attributes['middleware'])->toContain('api.sunset:2025-06-01,/api/v3/users');
});
it('preserves the existing deprecated signature without a replacement url', function () {
$routes = new class (1) extends VersionedRoutes {
public function attributes(): array
{
return $this->buildRouteAttributes();
}
};
$attributes = $routes->deprecated('2025-06-01')->attributes();
expect($attributes['middleware'])->toContain('api.sunset:2025-06-01');
expect($attributes['middleware'])->not->toContain('api.sunset:2025-06-01,/api/v3/users');
});