Laravel API 统一 JSON 格式需三步:1. 创建 ApiController 封装 success/error 方法;2. 重写 Handler.php 的 render() 统一异常响应;3. 使用 API Resource 和 routes/api.php 确保请求走 API 通道。

Laravel 接口返回统一格式的 JSON,核心不是“怎么输出 JSON”,而是“怎么让所有路径——无论成功、验证失败、404 还是 500——都返回结构一致、状态码准确、字段可控的 JSON”。只在控制器里写 response()->json(['data' => $user]) 是远远不够的,前端很快会遇到 message 在根级、data 有时缺失、错误时返回 HTML 或裸数组等问题。
用基类控制器封装 success/error 方法
新建 app/Http/Controllers/ApiController.php,继承默认 Controller,在里面定义标准化响应方法:
-
success($data, $message = 'OK', $code = 200):固定返回['code' => 0, 'message' => ..., 'data' => ...]结构(code 建议业务约定,如 0 表示成功) -
error($message, $code = 1001, $data = [], $httpStatus = 400):统一错误结构,$httpStatus控制 HTTP 状态码(如 422 用于验证失败) - 所有 API 控制器继承它,比如
UserController extends ApiController,直接调用$this->success($user)即可
必须重写异常处理器 render() 方法
这是最容易被跳过的一步。不改这里,404、ValidationException、QueryException 全都会跳出你定义的格式。打开 app/Exceptions/Handler.php,修改 render():
- 先判断是否为 API 请求:
if ($request->expectsJson()) { ... } -
ModelNotFoundException→ 返回['code' => 404, 'message' => '资源不存在', 'data' => []],状态码 404 -
ValidationException→ 提取$exception->errors(),返回code: 422+ 统一结构,状态码 422 - 其他未捕获异常(如 500)→ 生产环境只返回
['code' => 500, 'message' => '服务异常'],不暴露堆栈
配合 API Resource 控制数据结构
避免在控制器里手动 ->toArray() 漏字段或暴露敏感信息。运行:
php artisan make:resource UserResource- 在
toArray()中只定义要返回的字段,支持whenLoaded()、when()等条件逻辑 - 控制器中返回
new UserResource($user)或UserResource::collection($users) - 如需去掉外层
"data":{...}包裹,可在资源类中加JsonResource::withoutWrapping();
确保请求走的是 API 路由通道
统一格式的前提是 Laravel 能识别这是 API 请求:
- 所有接口路由必须注册在
routes/api.php(它自带api中间件组,含 JSON 协商能力) - 测试时用
curl -H "Accept: application/json" http://...,别直接在浏览器访问(浏览器默认发text/html) - 不要把
Route::middleware('api')加在web.php上——它不会触发 Laravel 的 API 响应逻辑


















