使用 php artisan make:controller --api 生成控制器可避免 web 相关方法(如 create、edit)和视图逻辑,仅保留 restful 方法;配合 route::apiresource() 使用可跳过 web 中间件(如 csrf、session),防止 419 错误;返回 json 应直接 return $data,由框架自动处理,无需手动 response()->json();验证失败返回 json 需确保请求头含 accept: application/json。

用 php artisan make:controller 生成 API 控制器时加 --api 参数
不加这个参数,生成的控制器默认带 create 和 edit 方法,它们面向 Web 页面,返回视图;API 接口不该有这些。加了 --api 后,Laravel 只生成标准 RESTful 方法(index、store、show、update、destroy),且方法体里连 return view(...) 都不会出现。
实操建议:
- 运行
php artisan make:controller PostController --api,别漏掉双横线 - 如果已生成普通控制器,别手动删方法——重命名或重建更安全,避免残留视图逻辑
-
--api不影响路由注册方式,它只改控制器骨架,后续还得配Route::apiResource()
在 routes/api.php 里用 Route::apiResource() 而不是 Route::resource()
两者路由规则看似一样,但关键区别在中间件:Route::apiResource() 默认不加载 web 中间件组(比如 VerifyCsrfToken、StartSession),而 API 请求不该走 CSRF 校验和 Session 写入。用错会导致 419 错误或会话冲突。
常见错误现象:
- POST 请求返回
419 Page Expired—— 很可能是用了Route::resource()绑定到api.php - 接口偶尔返回空响应或 500,查日志发现
SessionHandler报错 —— Session 在无状态 API 里被意外触发
正确写法:
Route::apiResource('posts', PostController::class);
返回 JSON 时别依赖 response()->json() 手动封装,直接 return 数组或模型
Laravel 的 API 响应机制会自动把数组、Eloquent 模型、集合转成 JSON,并设置 Content-Type: application/json。手动调 response()->json() 不仅冗余,还容易漏设状态码或覆盖默认头信息。
使用场景与参数差异:
- 简单列表:直接
return Post::all();,自动 200 + JSON - 单条记录:用
return $post;,比return response()->json($post, 200)更干净 - 需要自定义状态码或头:才用
response()->json(...),例如return response()->json(['error' => 'not found'], 404);
性能影响:手动封装多一次函数调用,无实质问题;但可读性和维护性下降,尤其团队协作时易引发风格混乱。
验证失败时返回 JSON 格式错误,确保前端能解析 errors 字段
Laravel 默认对 API 请求会自动返回 JSON 错误(含 message 和 errors),但前提是请求头带 Accept: application/json。很多前端发请求时没设这个头,导致验证失败返回 HTML 错误页,前端拿到一堆 HTML 字符串,JSON.parse() 直接崩。
容易踩的坑:
- Postman 或 curl 测试时不加
-H "Accept: application/json",看到的是 404/500 HTML 页面 - Vue/React 项目用
fetch未显式设headers.Accept,后端返回 HTML,前端报Unexpected token - 想全局强制 JSON 响应?别改异常处理器去硬塞头——优先检查客户端是否合规,这是契约问题
验证示例(在控制器中):
$validated = $request->validate([
'title' => 'required|string|max:255',
'body' => 'required|string'
]);只要请求头正确,出错就自然返回结构化 JSON。
复杂点在于跨域调试时,浏览器预检请求可能不带 Accept 头,这时候得靠 OPTIONS 响应兜底,但那是 CORS 配置的事,不是 API 逻辑本身的问题。









