Laravel 做 API 的核心是隔离请求上下文、关闭无关中间件、统一 JSON 返回与错误处理;必须用 routes/api.php、api 中间件组、JsonResource、自定义异常响应及正确 APP_URL 配置,否则只是伪 API。

直接说结论:Laravel 做 API 接口,核心不是“怎么写路由”,而是“怎么隔离请求上下文、关闭不必要的中间件、正确返回 JSON、处理错误一致性”——否则你写的只是带 json() 的普通路由,不是真正可用的 API。
为什么 Route::get('/api/users', ...) 不算合格的 API 路由
默认 Web 路由组会加载 EncryptCookies、VerifyCsrfToken、ShareErrorsFromSession 等中间件,它们对 API 完全无用,甚至会导致 419 错误(CSRF token missing)或 session 冲突。API 请求不该依赖 session 或 cookie 加密。
- 必须用
Route::middleware('api')显式指定 API 中间件组,它默认只启用ThrottleRequests和SubstituteBindings - 不要在
routes/web.php里写 API 路由;统一放在routes/api.php,它自动绑定api中间件组 - 若需自定义中间件(如 JWT 验证),应注册到
app/Http/Kernel.php的$middlewareGroups['api']里,而非全局堆叠
apiResource() 生成的控制器要改什么才能真正 RESTful
Laravel 的 apiResource() 生成的是「骨架」,不是开箱即用的 API。它默认返回 Eloquent 模型实例,而没做数据过滤、序列化控制或状态码约定。
- 必须重写
show()、store()等方法,用response()->json(..., 201)显式指定状态码(比如创建成功是 201,不是 200) - 模型需实现
toArray()或使用JsonResource类做字段裁剪(避免暴露password_hash、remember_token) - 不要直接
return $user;—— 这会触发 Eloquent 的默认 JSON 序列化,忽略隐藏字段配置;应写成return new UserResource($user);
如何让 404、422、500 错误也返回标准 JSON 格式
默认异常处理器对 API 请求仍可能返回 HTML 页面(尤其在本地环境开启 APP_DEBUG=true 时),破坏前端解析逻辑。
- 检查
app/Exceptions/Handler.php中的render()方法,加判断:if ($request->expectsJson()) { ... } - 对
ModelNotFoundException,手动转为response()->json(['message' => 'Not found'], 404),而不是依赖默认跳转 - 表单验证失败(
ValidationException)默认返回 422,但字段错误结构是['message' => ..., 'errors' => [...]]—— 前端是否真按这个结构取值?建议统一包装成['code' => 422, 'data' => []]风格
别忽略 APP_URL 和 ASSET_URL 对 API 的影响
看似无关的配置,实际会影响 JsonResource 里生成的 URL 字段(比如头像链接、资源详情页地址),尤其在前后端分离部署时。
- 确保
.env中APP_URL=https://api.example.com(不是前端域名),否则UrlGenerator会拼错 base path - 如果 API 返回图片路径,别用
asset('images/xxx.jpg')—— 它依赖ASSET_URL,而该配置常被设为空或错配;改用Storage::url()或硬编码 CDN 域名 - 调试时用
php artisan tinker执行url('/api/users')看输出,确认协议、host、port 是否符合预期
真正的难点不在写几个 json(),而在让整个请求生命周期不“泄露” Web 层的假设——从中间件、异常、序列化,到 URL 生成,每一步都要主动切断对 session、cookie、view、asset 的隐式依赖。漏掉任意一环,前端就可能收到 HTML 片段或 419 页面。


















