php 52 lines · 7 steps

Adding RFC 5988 Link headers in Laravel

A helper class turns a Laravel paginator into standard Link and X-* pagination headers on a JSON response.

Explained by highlit
1<?php
2 
3namespace App\Http\Support;
4 
5use Illuminate\Contracts\Pagination\LengthAwarePaginator;
6use Illuminate\Http\JsonResponse;
7 
8class PaginationLinkHeader
9{
10 public function attach(JsonResponse $response, LengthAwarePaginator $paginator): JsonResponse
11 {
12 $links = $this->buildLinks($paginator);
13 
14 if ($links !== []) {
15 $response->headers->set('Link', implode(', ', $links));
16 }
17 
18 $response->headers->set('X-Total-Count', (string) $paginator->total());
19 $response->headers->set('X-Page', (string) $paginator->currentPage());
20 $response->headers->set('X-Per-Page', (string) $paginator->perPage());
21 $response->headers->set('X-Total-Pages', (string) $paginator->lastPage());
22 
23 return $response;
24 }
25 
26 private function buildLinks(LengthAwarePaginator $paginator): array
27 {
28 $relations = array_filter([
29 'first' => $paginator->url(1),
30 'prev' => $paginator->previousPageUrl(),
31 'next' => $paginator->nextPageUrl(),
32 'last' => $paginator->url($paginator->lastPage()),
33 ]);
34 
35 $links = [];
36 
37 foreach ($relations as $rel => $url) {
38 $links[] = sprintf('<%s>; rel="%s"', $this->withPageQuery($url, $paginator), $rel);
39 }
40 
41 return $links;
42 }
43 
44 private function withPageQuery(string $url, LengthAwarePaginator $paginator): string
45 {
46 $separator = str_contains($url, '?') ? '&' : '?';
47 
48 return $url . $separator . http_build_query([
49 'per_page' => $paginator->perPage(),
50 ]);
51 }
52}
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1The RFC 5988 Link header lets API clients navigate pagination without parsing your response body.
  2. 2Filtering out null URLs keeps first/prev/next/last relations honest at the edges of a result set.
  3. 3Preserving query parameters when rewriting URLs avoids silently dropping the client's page size.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Adding RFC 5988 Link headers in Laravel — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code