本文目录导读:

在 Laravel 中,API 资源(API Resource)是用于转换和格式化 Eloquent 模型数据为 JSON 响应的强大工具,以下是几种转换方式:
创建 API 资源类
# 创建单个资源 php artisan make:resource UserResource # 创建资源集合 php artisan make:resource UserCollection --collection
基本转换
单个资源
// app/Http/Resources/UserResource.php
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->format('Y-m-d H:i:s'),
'role' => $this->role->name,
// 自定义字段
'full_name' => $this->first_name . ' ' . $this->last_name,
];
}
}
集合资源
// app/Http/Resources/UserCollection.php
class UserCollection extends ResourceCollection
{
public $collects = UserResource::class;
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => [
'total' => $this->resource->total(),
'current_page' => $this->resource->currentPage(),
],
];
}
}
在控制器中使用
use App\Http\Resources\UserResource;
use App\Http\Resources\UserCollection;
class UserController extends Controller
{
// 单个模型
public function show($id)
{
$user = User::findOrFail($id);
return new UserResource($user);
}
// 多个模型
public function index()
{
$users = User::paginate(10);
return UserResource::collection($users);
// 或使用集合
// return new UserCollection($users);
}
}
自定义响应格式
添加额外数据
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
// 关联资源
'posts' => PostResource::collection($this->whenLoaded('posts')),
// 条件字段
'secret' => $this->when($request->user()->isAdmin(), $this->secret),
];
}
// 自定义包装
public function with($request)
{
return [
'success' => true,
'version' => '1.0.0',
];
}
}
嵌套资源关系
class PostResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'author' => new UserResource($this->whenLoaded('user')),
'comments' => CommentResource::collection($this->whenLoaded('comments')),
];
}
}
高级转换技巧
条件属性
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
// 仅当关系加载时包含
'profile' => $this->when($this->relationLoaded('profile'), function () {
return new ProfileResource($this->profile);
}),
// 合并条件
$this->mergeWhen($this->isPremium(), [
'premium_features' => $this->premiumFeatures,
'expires_at' => $this->expiresAt,
]),
];
}
}
数据转换回调
class UserResource extends JsonResource
{
public function toArray($request)
{
return $this->transform(function ($user) {
return [
'id' => $user->id,
'name' => $user->name,
];
});
}
}
自定义 JSON 响应
class UserResource extends JsonResource
{
public function withResponse($request, $response)
{
$response->header('X-User-Resource', 'true');
$response->setStatusCode(200); // 自定义状态码
// 修改响应内容
$original = $response->getData();
$original->custom_data = '额外数据';
$response->setData($original);
}
}
资源集合的分页
class UserCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection,
'links' => [
'first' => $this->url(1),
'last' => $this->url($this->lastPage()),
'prev' => $this->previousPageUrl(),
'next' => $this->nextPageUrl(),
],
'meta' => [
'current_page' => $this->currentPage(),
'from' => $this->firstItem(),
'to' => $this->lastItem(),
'per_page' => $this->perPage(),
'total' => $this->total(),
],
];
}
}
最佳实践
- 保持资源类专注:每个资源类只处理一种模型的转换
- 避免业务逻辑:资源类只负责数据转换,不处理业务逻辑
- 使用 whenLoaded:避免 N+1 查询问题
- 缓存转换结果:对于频繁访问的数据
- 统一返回格式:保持 API 响应的一致性
通过 API 资源,你可以清晰地控制数据输出格式,避免在控制器中混合数据转换逻辑。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播