跳转到主要内容

什么是 API 资源

在构建 API 时,如果直接把 Eloquent 模型作为 JSON 返回,可能会泄露本该隐藏的字段,或者向客户端发送大量它并不需要的数据。 Eloquent API 资源在模型与 JSON 响应之间引入了一层转换层。可以通过 toArray() 方法明确地定义“响应里包含哪些内容,以什么格式呈现”。 主要好处包括:
  • 完全控制响应中包含的字段
  • 字段重命名、值加工可以集中在一个位置
  • 可以根据条件决定字段是否输出
  • 可以嵌套关联资源,保持结构一致

创建资源

使用 make:resource Artisan 命令生成资源类。
生成的类会被放到 app/Http/Resources 目录。
可以通过 $this 直接访问模型的属性。这是因为资源类内部会把访问代理到模型上。

在控制器中使用

定义好的资源可以直接从控制器或路由中返回。
或者使用模型的 toResource() 方法。
toResource() 会根据模型名自动查找对应的资源类(UserResource)。 默认情况下,响应会被包装在 data 键下。

资源集合

返回多个模型时使用 collection() 方法。
或者使用 Eloquent 集合的 toResourceCollection()

自定义集合资源

如果要给整个集合附加元数据,可以创建专门的集合资源。

字段的加工与转换

toArray() 中可以修改字段名或对值进行加工。

条件字段

when() — 根据条件添加字段

如果只在特定条件下才包含某个字段,可以使用 when()
when() 的条件为 false 时,整个键都会从响应中移除。

mergeWhen() — 一次性有条件地添加多个字段

若要按同一个条件批量决定多个字段是否输出,可以使用 mergeWhen()

whenLoaded() — 只包含已加载的关联

只在关联已经被 Eager Load 时才包含它,可以避免 N+1 问题,同时保持响应的灵活性。
由控制器负责决定是否加载关联。

whenCounted() — 条件性包含计数

用来在响应中有条件地包含通过 loadCount() 得到的关联计数。

嵌套资源

通过在关联上嵌套另一个资源类,可以保持响应结构一致。

添加元数据

with() — 顶层元数据

若要给整个集合附加元数据,可以重写 with() 方法。
响应示例:

additional() — 动态添加元数据

如果需要在控制器侧动态添加元数据,可以使用 additional()

与分页结合

把分页结果直接传给资源,就会自动附上 metalinks
或:
响应示例:
分页响应中即使调用了 withoutWrapping()data 键也总是会附上,以便与分页的 metalinks 键共存。

禁用数据包装

默认情况下,最外层的资源会被包装在 data 键下。若要禁用,可以在 AppServiceProviderboot() 中调用 withoutWrapping()
withoutWrapping() 只影响最外层的包装,你自己定义的 data 键不会被移除。

实战示例:用户 API 的实现

下面以用户管理 API 为例,展示如何使用资源来设计一致的响应。

UserResource

UserController

相关页面

Eloquent 关联入门

了解如何定义关联并使用预加载。

分页

查看如何将分页结果与 API 资源结合。
最后修改于 2026年7月18日