philiprehberger/laravel-api-versioning

Laravel middleware for API versioning with multi-source resolution from headers, Accept vendor types, and URL path segments

Maintainers

Package info

github.com/philiprehberger/laravel-api-versioning

pkg:composer/philiprehberger/laravel-api-versioning

Fund package maintenance!

philiprehberger

Statistics

Installs: 43

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.2.0 2026-04-07 03:42 UTC

This package is auto-updated.

Last update: 2026-04-07 03:43:08 UTC


README

Tests Latest Version on Packagist Last updated

Laravel middleware for API versioning with multi-source resolution from headers, Accept vendor types, and URL path segments.

Requirements

  • PHP 8.2+
  • Laravel 11 or 12

Installation

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.

Usage

Configuration

// 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,
];

Registering the Middleware

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'api.version' => \PhilipRehberger\ApiVersioning\ApiVersion::class,
    ]);
})
Route::middleware('api.version')->group(function () {
    // ...
});

Accessing the Current Version

use PhilipRehberger\ApiVersioning\ApiVersion;

$version = ApiVersion::current($request); // e.g. 'v2'

Version Resolution Priority

  1. X-API-Version request header
  2. Accept header vendor type: application/vnd.{vendor_name}.{version}+json
  3. URL path segment: /api/{version}/...
  4. Configured default version

API

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

Version Aliases

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

Deprecation Checks

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

SemVer-Style Versions

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

Custom Accept Header Pattern

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.

Response Headers

Header Values Meaning
X-API-Version v1, v2, ... The resolved version for this request
X-API-Deprecated true / false Whether this version is deprecated

Unsupported Version Response (400)

{
    "error": {
        "code": "unsupported_api_version",
        "message": "API version 'v99' is not supported.",
        "supported_versions": ["v1", "v2"]
    }
}

Development

composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT