Laravel生产环境多版本API需路由隔离、中间件独立、响应格式严格对齐:①用prefix+namespace物理隔离v1/v2,禁用重复/api前缀;②为各版本配置独立middleware组防限流冲突;③按版本硬绑定错误响应格式;④上线前强制route:clear && route:cache。

在Laravel生产环境中稳定运行多版本API,必须确保路由隔离、中间件独立、响应格式严格对齐,避免因缓存、日志或调试链路断裂引发线上故障。
用路由前缀+命名空间物理隔离v1/v2
打开 routes/api.php,删除所有顶层 Route::prefix('api') 套嵌——Laravel 默认已在 RouteServiceProvider 中注册 /api 前缀,重复添加会导致实际路径变成 /api/api/v1/users,404 错误难以定位。
为每个版本单独声明前缀与命名空间:
① 在 routes/api.php 底部追加:
Route::prefix('v1')->namespace('App\Http\Controllers\V1')->group(function () {<br> Route::apiResource('users', UserController::class);<br>});
② 紧接着写 v2 分组,必须显式指定完整控制器路径:
Route::prefix('v2')->namespace('App\Http\Controllers\V2')->group(function () {<br> Route::apiResource('users', UserController::class);<br>});
⚠️ 注意:不能省略 namespace(),否则 Laravel 会默认加载 App\Http\Controllers\UserController,而该类在 V1/V2 目录外并不存在;也不能写字符串 'UserController@index',PHP 自动加载机制无法推断命名空间,必报 【Class UserController not found】。
为各版本配置独立中间件组
进入 app/Http/Kernel.php,在 $middlewareGroups 数组中新增两个键:
'api.v1' => [<br> EnsureFrontendRequestsAreStateful::class,<br> ThrottleRequests::class . ':api,v1,60,1000',<br> TransformsRequest::class,<br>],
'api.v2' => [<br> EnsureFrontendRequestsAreStateful::class,<br> ThrottleRequests::class . ':api,v2,60,2000',<br> TransformsRequest::class,<br>],
回到 routes/api.php,将分组的 middleware() 参数从 'api' 改为对应版本组:Route::prefix('v1')->middleware('api.v1')->namespace(...)->group(...);Route::prefix('v2')->middleware('api.v2')->namespace(...)->group(...);
这一步不可跳过。若共用 api 组,v1 和 v2 将共享同一套限流规则,v2 上线后可能意外触发 v1 的速率限制,导致老客户端批量超时。
错误响应格式按版本硬绑定
方法一:重写异常处理器中的 render 方法
打开 app/Exceptions/Handler.php,在 render() 方法内插入判断逻辑:
if ($request->is('api/v2/*')) {<br> return response()->json([<br> 'error' => ['code' => $exception->getCode(), 'message' => $exception->getMessage()],<br> ], $exception->getStatusCode());<br>}
方法二:使用自定义响应宏(推荐)
在 AppServiceProvider::boot() 中注册:
Response::macro('apiV2Error', function ($message, $code = 400) {<br> return response()->json(['error' => ['code' => $code, 'message' => $message]], $code);<br>});
v2 控制器中直接调用:return response()->apiV2Error('Invalid token', 401);
v1 控制器仍用传统 response()->json(['message' => ...]) 格式,确保前端解析逻辑不被破坏。
上线前强制刷新路由缓存
执行命令:php artisan route:clear && php artisan route:cache
⚠️ 必须先清再缓,否则旧路由缓存未失效,新版本路由无法生效;缓存仅在 production 环境启用,本地开发无需执行此步。


















