-
Notifications
You must be signed in to change notification settings - Fork 0
feat(Http): #[Version] attribute for URL-versioned routes + Deprecation middleware #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
4ce27a3
feat(Http): #[Version] attribute for URL-versioned routes + Deprecati…
davidwyly a2d995a
fix(Http): three review concerns on the #[Version] primitive
davidwyly 2489861
fix(Http): address review feedback on Deprecation and VersionScannerTest
Copilot cca8253
fix(Http): four review concerns on the #[Version] primitive
davidwyly db3f18d
fix(Http): Version::applyTo() root path must not produce trailing slash
Copilot 806c1ab
fix(Http): root-path + version no longer produces a trailing slash
davidwyly 64d51cc
Merge branch 'feat/version-attribute' of github.com:davidwyly/rxn int…
davidwyly File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,3 +60,4 @@ Thumbs.db | |
|
|
||
| # Quickstart example's file-backed JSON store (created at request time) | ||
| /var/ | ||
| /.claude/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?php declare(strict_types=1); | ||
|
|
||
| namespace Rxn\Framework\Http\Attribute; | ||
|
|
||
| /** | ||
| * Mark a controller method (or class) as serving a specific API | ||
| * version. The Scanner reads this and prepends the version label | ||
| * to the registered route's path: | ||
| * | ||
| * #[Route('GET', '/products/{id:int}')] | ||
| * #[Version('v1')] | ||
| * public function showV1(int $id): array { ... } | ||
| * | ||
| * // → registered as GET /v1/products/{id:int} | ||
| * | ||
| * Class-level `#[Version]` applies to every method-level | ||
| * `#[Route]` in the class. Method-level `#[Version]` wins when | ||
| * both are present. | ||
| * | ||
| * Multiple versions of the same logical endpoint coexist | ||
| * naturally: `/v1/products/{id}` and `/v2/products/{id}` are | ||
| * distinct paths in the Router. The route-conflict detector | ||
| * (`bin/rxn routes:check`) sees them as such and doesn't flag | ||
| * them. | ||
| * | ||
|
davidwyly marked this conversation as resolved.
|
||
| * Deprecation: pass `deprecatedAt` and/or `sunsetAt` (any | ||
| * `DateTimeImmutable`-parseable date string — bare ISO dates | ||
| * like `'2026-01-01'`, full ISO 8601 with timezone, RFC 7231 | ||
| * IMF-fixdate, etc. all accepted) and the Scanner attaches a | ||
| * `Versioning\Deprecation` middleware that emits the corresponding | ||
| * RFC 8594 response headers — `Deprecation:` for "this version | ||
| * is on the way out" and `Sunset:` for "after this date, expect | ||
| * 410 Gone or removal." | ||
| * | ||
| * #[Version('v1', deprecatedAt: '2026-01-01', sunsetAt: '2026-12-31')] | ||
| * | ||
| * The version *label* is the API version, not the URL prefix: | ||
| * pass `'v1'` (Scanner adds the slash). Date-style versions | ||
| * (`'2025-10-15'`) and semantic versions (`'1.0'`) are also | ||
| * accepted — whatever the API contract decided. | ||
| */ | ||
| #[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)] | ||
| final class Version | ||
| { | ||
| public function __construct( | ||
| public readonly string $version, | ||
| public readonly ?string $deprecatedAt = null, | ||
| public readonly ?string $sunsetAt = null, | ||
| ) {} | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.