API Versioning
debt(d8/e7/b7/t6)
Closest to 'silent in production until users hit it' (d9), -1. The detection_hints confirm automated detection is 'no'. The absence of versioning is an architectural omission — no standard linter or SAST tool flags 'API routes without version prefix' automatically. It typically surfaces only when a breaking change is deployed and consumers fail. Scored d8 rather than d9 because a careful code review of route definitions can catch the missing /v1/ prefix before production.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says 'Add /v1/ prefix to all API routes from day one' — but the common_mistakes explicitly state 'retrofitting versioning breaks all existing URL references.' If versioning wasn't added from the start, every route, every consumer integration, documentation, and client SDK must be updated. This is a cross-cutting change that also requires coordinating with external consumers, pushing it firmly to e7.
Closest to 'strong gravitational pull' (b7). API versioning is an architectural decision that shapes how every future endpoint is defined, how routing is structured, how deprecation is managed, and how consumers interact with the system. Once a versioning strategy (or lack thereof) is established, every subsequent API change must conform to it. The tags confirm this is 'architecture'-level, and it applies to the web context broadly. It doesn't quite define the entire system's shape (b9) but it strongly shapes all API-related development.
Closest to 'notable trap' (t5), +1. The misconception states 'Adding a field to an API response is non-breaking' — this is a genuine trap because most developers assume additive changes are safe (following the robustness principle), but typed/strict consumers can break on unexpected fields. Additionally, using date-based versioning and not versioning from day one are common mistakes that competent developers fall into. The trap contradicts common intuition from general REST/API guidance that says additive changes are always backward-compatible, making it slightly worse than a standard documented gotcha.
Also Known As
TL;DR
Explanation
URI versioning (/v1/, /v2/) is the most visible and cache-friendly approach. Header versioning (Accept: application/vnd.api+json;version=2) keeps URLs clean but is harder to test in a browser. Content negotiation uses the Accept header's MIME type. Semantic versioning applied to APIs: breaking changes require a major version bump. Deprecation policy: announce deprecation, support both versions for a transition period, then remove. Never silently change a response field — add new fields alongside old ones.
Common Misconception
Why It Matters
Common Mistakes
- Not versioning from day one — retrofitting versioning breaks all existing URL references.
- Deprecating a version without announcing a timeline and giving consumers adequate migration time.
- Using dates as version identifiers (2024-01-01) — hard to compare and communicate breaking vs non-breaking changes.
Avoid When
- Do not version internal APIs used by a single team — the overhead outweighs the benefit.
- Avoid creating a new version for every change — only major breaking changes warrant a new version.
When To Use
- Version your API from the first public release — never ship an unversioned public API.
- Use URI versioning for public APIs — it is explicit, cacheable, and easy to route.
Code Examples
// No versioning — any change breaks consumers
Route::get('/api/users', [UserController::class, 'index']);
// Removing a field or changing a response structure breaks all clients silently
// URI versioning — simple, explicit, cache-friendly
// routes/api.php
Route::prefix('v1')->group(function () {
Route::get('/users', [V1\UserController::class, 'index']);
});
Route::prefix('v2')->group(function () {
Route::get('/users', [V2\UserController::class, 'index']);
});
// Add deprecation header on old version
header('Deprecation: version="v1", sunset="2026-12-31"');