Laravel 中用 make:resource 创建资源类是规范格式化 API 响应的标准做法,通过重写 toArray() 实现字段过滤、关系嵌套、条件包含及分页包装,比手动 json() 更清晰易维护。

在 Laravel 中,用 make:resource 创建资源类(Resource),是规范、可复用地格式化 API 返回数据的标准做法。它把模型(或数组)转换成统一结构的 JSON 响应,支持字段过滤、关系嵌套、条件包含、分页包装等,比手动 return response()->json() 更清晰、更易维护。
1. 创建 Resource 类
运行 Artisan 命令生成资源类:
php artisan make:resource UserResource
默认会生成在 app/Http/Resources/UserResource.php。它继承自 Illuminate\Http\Resources\Json\JsonResource,核心是重写 toArray() 方法:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toIso8601String(),
];
}2. 在控制器中使用 Resource
单个资源直接 new 或静态调用 ::make():
use App\Http\Resources\UserResource;
public function show(User $user)
{
return new UserResource($user);
// 或等价写法:
// return UserResource::make($user);
}集合用 UserResource::collection():
public function index()
{
return UserResource::collection(User::all());
// 也可传分页结果(自动识别并包装为 pagination 结构)
// return UserResource::collection(User::paginate(10));
}3. 处理关联与条件字段
在 toArray() 中可安全访问模型关系(N+1 已被 Eloquent 预加载优化):
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'posts' => PostResource::collection($this->whenLoaded('posts')),
'is_active' => $this->when($this->status === 'active', true),
'avatar_url' => $this->when($this->hasMedia('avatar'),
$this->getFirstMediaUrl('avatar')
),
];
}-
$this->whenLoaded('relation'):仅当该关系已预加载时才包含 -
$this->when(condition, value):按条件决定是否包含字段 - 推荐在控制器中用
with()预加载,避免 N+1
4. 自定义响应结构(如加 data 包裹)
若需统一返回 {"data": {...}} 格式,可在 Resource 类中覆盖 with() 方法:
public function with($request)
{
return ['success' => true];
}
// 或重写 toResponse() 实现完全自定义结构
public function toResponse($request)
{
return response()->json([
'data' => $this->resource,
'message' => 'OK',
'code' => 200,
]);
}注意:toResponse() 会跳过默认 JSON 封装,适合全局统一响应格式;但建议只在顶层 Resource(如 ApiResource)中使用,避免每个资源都重写。











