如何为单条Laravel Eloquent API资源添加prev和next链接
如何为单条Laravel Eloquent API资源添加prev和next链接
当我们使用pagination()方法返回资源集合时,Laravel会自动生成包含first、last、prev、next的分页链接。但如果需要在单条记录的详情接口(比如show方法)中也添加prev和next链接,实现类似的导航效果,可以通过以下两种简单方式实现:
方法一:在API资源类中封装链接逻辑
直接在对应的资源类中添加with方法,统一处理链接生成逻辑,这样所有使用该资源的接口都会自动带上导航链接。
修改ServiceResource类:
<?php namespace App\Http\Resources; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; class ServiceResource extends JsonResource { /** * 定义资源的数组表示 */ public function toArray(Request $request): array { return parent::toArray($request); // 也可以在这里自定义单条记录的返回字段 // return [ // 'id' => $this->id, // 'name' => $this->name, // // 其他字段... // ]; } /** * 添加额外的响应数据(这里用来生成prev/next链接) */ public function with(Request $request): array { // 查询上一条记录的ID(按ID排序) $prevId = $this->where('id', '<', $this->id)->max('id'); // 查询下一条记录的ID(按ID排序) $nextId = $this->where('id', '>', $this->id)->min('id'); $links = []; if ($prevId) { $links['prev'] = route('services.show', $prevId); } if ($nextId) { $links['next'] = route('services.show', $nextId); } return [ 'links' => $links, ]; } }
然后控制器的show方法可以简化为:
public function show(Service $service): ServiceResource { return new ServiceResource($service); }
方法二:在控制器中直接生成链接
如果不想修改资源类,也可以在控制器的show方法中单独查询并添加链接:
public function show(Service $service): ServiceResource { // 查询上一条和下一条记录的ID $prevId = Service::where('id', '<', $service->id)->max('id'); $nextId = Service::where('id', '>', $service->id)->min('id'); $links = []; if ($prevId) { $links['prev'] = route('services.show', $prevId); } if ($nextId) { $links['next'] = route('services.show', $nextId); } // 使用additional方法添加额外的链接数据 return (new ServiceResource($service))->additional([ 'links' => $links ]); }
注意事项:自定义排序逻辑
如果你的记录不是按ID排序,而是按created_at或其他字段排序,需要调整查询逻辑。比如按创建时间排序时:
// 上一条:创建时间早于当前记录的最新一条 $prev = Service::where('created_at', '<', $service->created_at) ->orderBy('created_at', 'desc') ->first(); // 下一条:创建时间晚于当前记录的最早一条 $next = Service::where('created_at', '>', $service->created_at) ->orderBy('created_at', 'asc') ->first(); $links = []; if ($prev) { $links['prev'] = route('services.show', $prev->id); } if ($next) { $links['next'] = route('services.show', $next->id); }
这样处理后,接口返回的响应就会包含data字段(单条记录详情)和links字段(包含prev和next链接),完全符合你需要的格式。
内容的提问来源于stack exchange,提问作者kicaj
相关产品推荐
相关产品推荐

