Laravel middleware for API versioning with multi-source resolution from headers, Accept vendor types, and URL path segments
composer require philiprehberger/laravel-api-versioningLaravel middleware for API versioning with multi-source resolution from headers, Accept vendor types, and URL path segments.
composer require philiprehberger/laravel-api-versioning
Laravel's package auto-discovery registers the service provider automatically.
Publish the config file:
php artisan vendor:publish --tag=api-versioning-config
This creates config/api-versioning.php.
// config/api-versioning.php
return [
'supported_versions' => ['v1', 'v2'],
'default_version' => 'v1',
'latest_version' => 'v2',
'deprecated_versions' => [],
'vendor_name' => 'myapp',
'header' => 'X-API-Version',
'response_headers' => true,
];
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'api.version' => \PhilipRehberger\ApiVersioning\ApiVersion::class,
]);
})
Route::middleware('api.version')->group(function () {
// ...
});
use PhilipRehberger\ApiVersioning\ApiVersion;
$version = ApiVersion::current($request); // e.g. 'v2'
X-API-Version request headerAccept header vendor type: application/vnd.{vendor_name}.{version}+json/api/{version}/...| Method / Concept | Description |
|---|---|
ApiVersion::current(Request $request) | Get the resolved API version for the current request |
ApiVersion::aliases() | Get the configured version aliases as an associative array |
ApiVersion::resolveAlias(string $alias) | Resolve an alias to its version string, or null if not found |
ApiVersion::isDeprecated(string $version) | Check whether a version is deprecated (in deprecated_versions or not the latest_version) |
ApiVersion middleware | Resolves version (with alias support), sets request attribute, adds response headers |
X-API-Version response header | The resolved version for each request |
X-API-Deprecated response header | true / false — whether this version is deprecated |
Map friendly names to version strings so clients can request latest or stable instead of a specific version number:
// config/api-versioning.php
'aliases' => [
'latest' => 'v2',
'stable' => 'v1',
],
When the middleware resolves a version that matches an alias key, it transparently replaces it with the target version. For example, sending X-API-Version: latest is treated as X-API-Version: v2.
You can also resolve aliases programmatically:
use PhilipRehberger\ApiVersioning\ApiVersion;
ApiVersion::aliases(); // ['latest' => 'v2', 'stable' => 'v1']
ApiVersion::resolveAlias('latest'); // 'v2'
ApiVersion::resolveAlias('unknown'); // null
Check whether a version is deprecated programmatically:
use PhilipRehberger\ApiVersioning\ApiVersion;
ApiVersion::isDeprecated('v1'); // true if v1 is in deprecated_versions or not latest_version
ApiVersion::isDeprecated('v2'); // false if v2 === latest_version
In addition to the simple v1, v2 form, the URL path and Accept header resolvers also match SemVer-style versions like v1.2, v1.2.3, etc. List them in supported_versions to enable:
'supported_versions' => ['v1', 'v1.2', 'v1.2.3', 'v2'],
GET /api/v1.2.3/users
Accept: application/vnd.api.v1.2.3+json
Override the default application/vnd.{vendor_name}.{version}+json matcher with a custom regex via accept_header_pattern. The first capture group must contain the version string:
// config/api-versioning.php
'accept_header_pattern' => '/application\/json;\s*version=(v\d+(?:\.\d+){0,2})/',
Accept: application/json; version=v2
When accept_header_pattern is null, the default vendor type pattern is used.
| Header | Values | Meaning |
|---|---|---|
X-API-Version | v1, v2, ... | The resolved version for this request |
X-API-Deprecated | true / false | Whether this version is deprecated |
{
"error": {
"code": "unsupported_api_version",
"message": "API version 'v99' is not supported.",
"supported_versions": ["v1", "v2"]
}
}
composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse
If you find this project useful: