本文目录导读:

在 Laravel 中,可以通过多种方式实现版本路由的共存,但框架本身并没有内置一个专门的“版本路由”功能,下面介绍几种常见的实现方案:
最直接的方式:路由文件拆分
将不同版本的 API 路由放在不同的文件中:
// routes/api_v1.php
Route::get('/users', [UserController::class, 'index']);
// routes/api_v2.php
Route::get('/users', [UserControllerV2::class, 'index']);
在 RouteServiceProvider 中分别加载:
protected function mapApiRoutes()
{
Route::prefix('api/v1')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api_v1.php'));
Route::prefix('api/v2')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api_v2.php'));
}
URL 前缀分组
在 routes/api.php 中按版本分组:
// routes/api.php
Route::prefix('v1')->group(function () {
Route::get('/users', [UserController::class, 'index']);
Route::get('/posts', [PostController::class, 'index']);
});
Route::prefix('v2')->group(function () {
Route::get('/users', [UserController::class, 'show']);
Route::get('/posts', [PostControllerV2::class, 'index']);
});
使用子域名
通过子域名区分版本:
Route::group(['domain' => 'v1.api.example.com'], function () {
Route::get('/users', [UserController::class, 'index']);
});
Route::group(['domain' => 'v2.api.example.com'], function () {
Route::get('/users', [UserController::class, 'indexV2']);
});
通过请求头(Accept Header)
根据 Accept 请求头返回不同内容:
Route::get('/users', function (Request $request) {
if ($request->header('Accept') === 'application/vnd.api.v2+json') {
return (new UserControllerV2())->index();
}
return (new UserControllerV1())->index();
});
使用中间件实现版本路由
创建版本识别中间件:
// app/Http/Middleware/APIVersion.php
public function handle($request, Closure $next, $version)
{
$request->attributes->set('api_version', $version);
return $next($request);
}
// 注册中间件并应用
Route::prefix('api')
->middleware('api')
->group(function () {
Route::prefix('v1')
->middleware('api.version:v1')
->group(base_path('routes/api_v1.php'));
Route::prefix('v2')
->middleware('api.version:v2')
->group(base_path('routes/api_v2.php'));
});
推荐方案
对于大多数项目,推荐使用第1种或第2种方式:
- 简单清晰:代码易读易维护
- 性能好:没有额外的解析负担
- 灵活:可以完全独立控制不同版本的逻辑
- 便于测试:不同版本的测试可以完全分离
如果需要更复杂的版本策略(如同时支持多个版本、自动适配等),可以考虑使用社区包如 m1guelpf/laravel-api-version 或自定义中间件。
注意:建议在项目初期就规划好版本策略,避免后续大规模重构,版本路由的选择应该根据你的 API 设计哲学(URL版本 vs Header版本)和业务复杂度来决定。