SyntaxStudy
Sign Up
REST API URL, Header, and Query String Versioning
REST API Beginner 1 min read

URL, Header, and Query String Versioning

API versioning lets you evolve a REST API without breaking existing clients. There are three main strategies: URL path versioning (/v1/users), request header versioning (Accept: application/vnd.api+json;version=2), and query string versioning (/users?v=2). URL versioning is the most visible and easiest to test in a browser; header versioning is cleaner but harder to debug. A breaking change is anything that removes or renames a field, changes a field's type, alters a status code, or modifies resource URL structure. Adding optional fields, adding new endpoints, and adding new enum values are typically non-breaking and do not require a version bump.
Example
# ----- URL path versioning (most common) -----
GET /api/v1/users/42   HTTP/1.1
GET /api/v2/users/42   HTTP/1.1  <- breaking change warrants new version

# Laravel routes/api.php
Route::prefix('v1')->group(function () {
    Route::apiResource('users', V1\UserController::class);
    Route::apiResource('posts', V1\PostController::class);
});

Route::prefix('v2')->group(function () {
    Route::apiResource('users', V2\UserController::class);
    Route::apiResource('posts', V2\PostController::class);
});

# ----- Header versioning -----
GET /users/42 HTTP/1.1
Accept: application/vnd.myapi.v2+json

# ----- Query string versioning -----
GET /users/42?version=2 HTTP/1.1

# ----- Sunset header: deprecate old versions -----
GET /api/v1/users/42 HTTP/1.1

HTTP/1.1 200 OK
Sunset: Sat, 31 Dec 2025 23:59:59 GMT
Deprecation: Mon, 01 Jan 2025 00:00:00 GMT
Link: <https://api.example.com/v2/users/42>; rel="successor-version"
{ "id": 42, "name": "Alice" }