API Versioning in Laravel 11
Why Version Your Laravel App?
As a backend engineer, versioning your app is an essential workflow in development. It allows you to make necessary updates without disrupting existing environments or breaking earlier versions of your API. Versioning also helps frontend engineers know exactly which version of the API they’re working with, promoting smoother collaboration.
Versioning in Laravel 11 vs. Earlier Versions
In previous Laravel versions, API versioning was typically configured in the RouteServiceProvider.php
file located in the app/Providers
directory. Here's what the setup looked like:
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/home';
public function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
}
Key Breakdown:
$this->routes(function () {...});
: Loads and groups routes for both web and API.Route::middleware('api')
: Appliesapi
middleware (handles rate limiting and request formatting).->prefix('api')
: Prefixes all API routes with/api
.->group(base_path('routes/api.php'))
: Loads API routes fromroutes/api.php
.Route::middleware('web')
: Loads web-based routes.->group(base_path('routes/web.php'))
: Loads web routes fromroutes/web.php
.
Versioning in Laravel 11
Laravel 11 introduces changes aimed at reducing unnecessary files and providing better abstraction. As a result, RouteServiceProvider.php
is no longer scaffolded by default. Instead, versioning configuration happens in bootstrap/app.php
.
Here’s how the new setup looks:
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function (){
Route::middleware('api')
->prefix('api/v1')
->group(__DIR__.'/../routes/api_v1.php');
}
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
Key Breakdown:
web: __DIR__.'/../routes/web.php'
: Loads web routes.api: __DIR__.'/../routes/api.php'
: Loads API routes.commands: __DIR__.'/../routes/console.php'
: Loads Artisan console commands.health: '/up'
: Sets up a health check endpoint.then: function () {...}
: Adds versioning logic for API routes. It creates a versioned group (api/v1
).
This method allows flexibility and maintains API versioning control.
Generating API Routes
To start, you need to generate the api.php
file, which isn’t scaffolded by default in Laravel 11. Run:
php artisan install:api
This will create the routes/api.php
file. Now, copy this file and rename it to api_v1.php
to match the version prefix used in bootstrap/app.php
. This file will handle all your version 1 (/api/v1/
) endpoints.
Next, define your routes inside api_v1.php
:
Route::apiResource('tickets', TicketController::class);
The apiResource
method generates routes for API-specific CRUD operations in a streamlined manner, excluding web-specific routes like create
and edit
.
Creating the Controller
Run the following command to create the necessary controller:
php artisan make:controller "Api/V1/TicketController" --resource --model=Ticket --request
This command generates a resource controller (TicketController
) in the Api/V1
namespace, with CRUD methods linked to the Ticket
model. The --request
flag also generates a form request class for handling validation.
Testing Your API
You can now test your versioned API in Postman by using endpoints like:
http://ticketeer.test/api/v1/tickets
I hope now you get to know how to build and test versioned APIs in Laravel 11.
I’m sharing what I’ve learned about Laravel over the past few weeks as I’ve been getting familiar with it. For those with more experience in Laravel, feel free to share your feedback or how you’ve approached versioning in your own projects!
Subscribe to my newsletter
Read articles from Mustapha Abdul-Rasaq (Geekmaros) directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mustapha Abdul-Rasaq (Geekmaros)
Mustapha Abdul-Rasaq (Geekmaros)
A Developer who loves Vue