必须先安装 darkaonline/l5-swagger 包,否则 @OA\Get 等注解无效;需匹配 Laravel 版本(Laravel 11 用 ^8.4+),发布配置后正确设置 paths.annotations,并确保注解路径、参数名与 routes/api.php 完全一致,手动定义 @OA\Schema 响应体,启用 SWAGGER_UI_ENABLED 并确认路由存在。

用 @OA\Get 这类注解前,先装好 darkaonline/l5-swagger
不装这个包,写再多 @OA\Get、@OA\Parameter 注解都没用——Laravel 不会识别,php artisan l5-swagger:generate 会直接报错说找不到类。它不是 Laravel 自带的,也不是 PHP-FIG 标准,纯靠这个包把注解翻译成 OpenAPI JSON。
安装时注意 Laravel 版本匹配:darkaonline/l5-swagger:^8.0 对应 Laravel 9/10;Laravel 11 要用 ^8.4 以上(否则 config/l5-swagger.php 里 routes.api 配置项会失效)。
- 运行
composer require "darkaonline/l5-swagger:^8.4"后,务必执行php artisan vendor:publish --provider="L5Swagger\L5SwaggerServiceProvider" - 发布后检查
config/l5-swagger.php中的paths.annotations,默认是app/Http/Controllers,如果你的 API 控制器在app/Http/Controllers/Api/V1,得手动加进去,不然扫描不到 - 别在
routes/web.php里写 API 注解——路由没注册到 API 中间件组,Swagger UI 点“Try it out”会 401 或 404
@OA\Get 和 @OA\Post 必须和路由定义对齐
注解不是装饰品,它得和 routes/api.php 里的实际路由完全一致:HTTP 方法、URL 路径、参数占位符名称,一个字符都不能差。比如路由写的是 Route::get('/users/{id}', [UserController::class, 'show']),那注解里的 path="/users/{id}" 就不能写成 /users/{user_id},否则 Swagger UI 里生成的请求 URL 是错的,调试时永远 404。
- 路径参数名必须一致:
{id}就是{id},别改成{userId},哪怕变量名在方法里叫$userId - 查询参数(
?page=1&sort=name)要用@OA\Parameter(name="page", in="query", ...)显式声明,不写就不会出现在文档的“Parameters”面板里 - 如果路由用了前缀如
Route::prefix('api/v1')->group(...),注解里的path就只写/users,不要重复写/api/v1/users,否则生成的路径会变成双份前缀
@OA\Schema 定义响应体时,别直接引用 Eloquent 模型类
@OA\Schema(ref="#/components/schemas/User") 看起来省事,但一旦模型字段动态变化(比如加了 appends、改了 $casts、用了 makeHidden),文档就和真实返回不一致。Swagger 不会运行 PHP 代码去反射模型,它只认你手写的 @OA\Property。
更麻烦的是:Eloquent 的 $dates、$casts、访问器(accessor)不会自动转成 OpenAPI 类型。比如 is_active 是 tinyint(1),PHP 返回布尔值,但没声明 type="boolean",Swagger 就当它是整数,前端 Typescript 生成器会产出错误类型。
- 响应体老实用
@OA\Schema+@OA\Property手动列字段,尤其注意type和format(date-time不能写成datetime) - 数组字段写
@OA\Property(type="array", @OA\Items(type="string")),别漏掉@OA\Items,否则 Swagger UI 显示 “unknown type” - 如果返回的是资源集合(
UserResource::collection()),注解里要写@OA\Response(... @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/User"))),不是直接 ref 到单个 schema
生成文档后打不开 UI?检查 SWAGGER_UI_ENABLED 和中间件
运行 php artisan l5-swagger:generate 成功,不代表能访问 /api/documentation。默认配置下,这个路由只在 APP_ENV=local 时启用,生产环境直接 404。另外,Laravel 10+ 默认加了 PreventRequestsDuringMaintenance 中间件,如果站点进了维护模式,Swagger UI 也进不去,但错误提示是 503,容易误判为配置问题。
- 临时开启:在
.env加SWAGGER_UI_ENABLED=true,并确保APP_ENV=local或在config/l5-swagger.php里把swagger_ui_enabled设为true - 访问路径是
/api/documentation(不是/docs或/swagger),且必须走 HTTPS(如果APP_URL配了 https) - 如果用了 Sanctum 或 Passport,Swagger UI 的 “Authorize” 按钮点开后填的是 Bearer Token,但实际请求头要加
Authorization: Bearer xxx,少个空格或大小写错误都会 401
最常被忽略的是:注解写在控制器方法里,但那个方法根本没被路由指向——生成的 JSON 里压根没有这条接口,UI 上自然看不到。别只盯着注解语法,先 php artisan route:list | grep users 确认路由存在。


















