必须用 resource 类做 api 数据格式转换,它是数据流强制闸门;字段需显式声明,关联须预加载+whenloaded,分页需链式 response() 或自定义集合类,openapi 文档须手动注解。

必须用 Resource 类做 API 数据格式转换,直接 toArray() 或手动构造数组会失控——字段漏写、N+1、敏感信息暴露、分页结构丢失,全在控制器里硬拼时埋下。
Resource 类的 toArray() 是唯一可信出口
它不是“美化层”,而是数据流强制闸门。返回什么,JSON 就长什么样;没写的字段,前端永远收不到;写错逻辑,就直接暴露密码或 null 引用。
-
$this->name会触发模型访问器,但前提是这一行被显式写进toArray()返回数组里 - 日期别依赖模型
$casts或全局设置:$this->created_at?->toISOString()才可靠,?->防 null - 关联字段不能直接写
'posts' => $this->posts——未预加载时会懒加载,一次请求变几十次查询 - 要嵌套关联,必须配合
$this->whenLoaded('posts', fn() => PostResource::collection($this->posts))
UserResource::collection() 不等于循环 new
它跳过单个资源构造函数,批量处理,性能更好,也避免了你在 __construct() 里加日志、缓存等副作用被意外执行。
- 传
collect([])返回空数组[];传null给new UserResource($user)直接报错 - 如果用了分页(如
User::paginate(10)),UserResource::collection($users)只返回data数组,links和meta全丢——必须链式调用->response() - 想加
data包裹或自定义分页字段,得单独建集合类:php artisan make:resource UserCollection --collection,并在toArray()里手动组织结构
条件字段和敏感字段靠显式控制,不靠“默认过滤”
Resource 没有自动白名单或隐藏规则。漏写 = 安全,写错 = 泄露。所有判断都得你亲手写进 toArray()。
- 用
$this->when($this->can('admin'), 'is_admin')替代 if 分支,兼容 collection 场景 - 批量加调试字段:
mergeWhen($request->user()->isSuperAdmin(), ['sql_log' => []]) - 永远不要在
toArray()里调用$this->load()或复杂模型方法——资源应无状态,查询必须由控制器预加载完成 - 字段映射别硬编码:数据库存
active,前端要is_active,就在toArray()里写'is_active' => (bool) $this->active
OpenAPI 文档不会自动读取 Resource 类
无论你把 toArray() 写得多规范,scribe 或 laravel-openapi 都不会去解析它。它们只认控制器方法上的注解。
- 返回集合时,必须写
@responseCollection App\Http\Resources\UserResource,不能只写@response - 用了
when()动态字段?得用@responseField nullable显式标注可选性 - 嵌套了
$this->whenLoaded('profile')?文档里不会自动展开profile.id,得手写@responseField profile.id - 自定义响应包装(如
return response()->json(['items' => $resource]))?必须用@response贴 JSON 示例,否则文档为空
真正容易被忽略的点是:资源类里没有“魔法”,只有你写的每一行 PHP 逻辑;而最危险的疏忽,往往发生在你认为“这个字段肯定有值”“那个关联肯定已加载”的时候。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











