laravel-api-versioning maintained by jeromejhipolito
Description
Header-based API versioning with version flags for Laravel. Supports semantic versioning and feature flag-like version control.
Author
Last update
2026/01/22 08:59
(dev-main)
License
Downloads
120
Tags
Laravel API Versioning
Header-based API versioning with version flags for Laravel. Supports semantic versioning and feature flag-like version control.
Features
- 🏷️ Header-based versioning - Uses
X-API-Versionheader (industry standard like Stripe, GitHub) - 📦 Semantic versioning - Full support for major.minor.patch format (1.0.0, 1.1.0, 2.0.0)
- 🚩 Version flags - Enable/disable versions independently (perfect for app store review periods)
- 🔒 Minimum version middleware - Require minimum version per route:
min.version:1.1.0 - 🔄 Controller inheritance - Override only changed methods in versioned controllers
- 📱 Mobile-friendly - Disabled versions return
version_enabled: falseso apps can hide features - 🌍 Translations - Built-in support for English, Japanese, and Korean
Installation
composer require jeromejhipolito/laravel-api-versioning
Publish Configuration (Optional)
php artisan vendor:publish --tag=api-versioning-config
php artisan vendor:publish --tag=api-versioning-lang
Configuration
Add to your .env:
# Optional: Comma-separated list of enabled versions (null = all enabled)
API_ENABLED_VERSIONS=1.0.0,1.1.0
# Optional: Default version when header is missing
API_DEFAULT_VERSION=1.0.0
Edit config/api-versioning.php:
return [
'supported_versions' => ['1.0.0', '1.1.0', '2.0.0'],
'enabled_versions' => env('API_ENABLED_VERSIONS')
? array_map('trim', explode(',', env('API_ENABLED_VERSIONS')))
: null, // null = all supported versions enabled
'default_version' => env('API_DEFAULT_VERSION', '1.0.0'),
];
Register Middleware
In bootstrap/app.php:
use JeromeJHipolito\ApiVersioning\Middleware\ApiVersionMiddleware;
use JeromeJHipolito\ApiVersioning\Middleware\ResolveVersionedController;
->withMiddleware(function (Middleware $middleware) {
$middleware->api(append: [
ApiVersionMiddleware::class,
ResolveVersionedController::class,
]);
})
Usage
Making Requests
# With version header
curl -H "X-API-Version: 1.0.0" https://api.example.com/users
# Without header (uses default version)
curl https://api.example.com/users
Response Headers
Every response includes:
X-API-Version: 1.0.0X-API-Version-Enabled: trueX-API-Supported-Versions: 1.0.0, 1.1.0, 2.0.0X-API-Enabled-Versions: 1.0.0, 1.1.0
Check Version Status
GET /api/version/status
{
"status": "success",
"data": {
"current_version": "1.0.0",
"version_enabled": true,
"default_version": "1.0.0",
"supported_versions": ["1.0.0", "1.1.0", "2.0.0"],
"enabled_versions": ["1.0.0", "1.1.0"],
"version_flags": {
"1.0.0": true,
"1.1.0": true,
"2.0.0": false
}
}
}
Using in Controllers
use JeromeJHipolito\ApiVersioning\Traits\VersionAwareTrait;
class UserController extends Controller
{
use VersionAwareTrait;
public function show($id)
{
$user = User::find($id);
// Check version
if ($this->isVersionAtLeast('2.0.0')) {
return new V2\UserResource($user);
}
return new UserResource($user);
}
}
Using in Resources
use JeromeJHipolito\ApiVersioning\Traits\VersionAwareResourceTrait;
class UserResource extends JsonResource
{
use VersionAwareResourceTrait;
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
// Only in 1.1.0+
...$this->mergeWhenVersion('1.1.0', [
'profile_score' => $this->profile_score,
]),
// Only below 2.0.0 (deprecated)
...$this->mergeWhenVersionBelow('2.0.0', [
'legacy_field' => $this->old_data,
]),
];
}
}
Disabled Version Response
When a version is supported but not enabled:
{
"status": "success",
"version_enabled": false,
"message": "This API version is currently disabled...",
"current_version": "2.0.0",
"data": null
}
This allows mobile apps to check version_enabled and hide features accordingly.
Version Flags Workflow
-
Add new version as supported but disabled
'supported_versions' => ['1.0.0', '2.0.0'],API_ENABLED_VERSIONS=1.0.0 -
Deploy to production - Old apps continue working
-
Submit new app version - App checks
version_flagsand hides 2.0.0 features -
After app store approval - Enable the version
API_ENABLED_VERSIONS=1.0.0,2.0.0
Minimum Version Middleware
Require a minimum API version for specific routes or groups:
Register the Middleware Alias
In bootstrap/app.php:
use JeromeJHipolito\ApiVersioning\Middleware\MinimumVersionMiddleware;
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'min.version' => MinimumVersionMiddleware::class,
]);
})
Usage
// Single route
Route::post('new-feature', [FeatureController::class, 'store'])
->middleware('min.version:1.1.0');
// Route group
Route::group(['middleware' => ['min.version:2.0.0']], function () {
Route::post('advanced', [AdvancedController::class, 'store']);
Route::delete('advanced/{id}', [AdvancedController::class, 'destroy']);
});
Response When Version Is Too Low
{
"message": "This endpoint requires API version 1.1.0 or higher",
"current_version": "1.0.0",
"minimum_version": "1.1.0"
}
HTTP Status: 400 Bad Request
Available Methods
VersionAwareTrait (Controllers)
| Method | Description |
|---|---|
getApiVersion() |
Get current version string |
getApiMajorVersion() |
Get major version number |
getApiMinorVersion() |
Get minor version number |
getApiPatchVersion() |
Get patch version number |
isVersionAtLeast($v) |
Check if >= version |
isVersionBelow($v) |
Check if < version |
isVersionExactly($v) |
Check if exact version |
isVersionBetween($min, $max) |
Check if in range |
VersionAwareResourceTrait (Resources)
| Method | Description |
|---|---|
mergeWhenVersion($v, $array) |
Merge array if >= version |
mergeWhenVersionBelow($v, $array) |
Merge array if < version |
mergeWhenVersionExactly($v, $array) |
Merge array if exact version |
mergeWhenVersionBetween($min, $max, $array) |
Merge if in range |
whenVersion($v, $value, $default) |
Return value if >= version |
whenVersionBelow($v, $value, $default) |
Return value if < version |
License
MIT License. See LICENSE for details.