Implementing Links in Responses: HATEOAS for Better APIs
Learn to include "self" and pagination links in your JSON API responses. Make your REST API discoverable and easier for clients to consume.

Previously in this course, we covered REST API Design: Implementing HATEOAS for Discoverable Navigation and REST API Design: Balancing Resource Embedding and Over-Fetching. In this lesson, we move from theory to implementation by adding "self" links and pagination navigation to your Task Manager API.
Why "Self" and Pagination Links Matter
In a well-designed REST API, the client shouldn't have to guess or hard-code complex URL construction logic. By providing links directly in the JSON response, you provide a roadmap for the client.
A "self" link confirms the current resource's canonical URI, while pagination links allow the client to iterate through a collection without manually building strings like /v1/tasks?limit=10&offset=20.
Implementing "Self" Links
A "self" link is the most basic form of hypermedia. It tells the client: "This is where you can find this exact resource again."
When returning a single task, add a _links or links object to your JSON envelope. Keeping this consistent across your API is crucial for Mastering JSON Responses in Express.js for REST APIs.
JSON{ "data": { "id": "task_123", "title": "Complete documentation", "status": "pending" }, "links": { "self": "/v1/tasks/task_123" } }
Adding Pagination Links to Collections
When returning a collection, you need to provide links to move forward (next) and backward (prev). This keeps the client logic decoupled from your pagination strategy (e.g., if you decide to switch from offset to cursor-based pagination later, the client just follows the link).
Here is how a collection response looks with navigation:
JSON{ "data": [ { "id": "task_1", "title": "Setup project" }, { "id": "task_2", "title": "Write tests" } ], "meta": { "total": 50, "limit": 2, "offset": 0 }, "links": { "self": "/v1/tasks?limit=2&offset=0", "next": "/v1/tasks?limit=2&offset=2", "prev": null } }
Practical Implementation: The Task Manager
To implement this in your project, modify your response formatter. Instead of returning raw data, pass it through a function that attaches the links object.
| Link Type | Purpose | Logic |
|---|---|---|
self | Canonical URI | base_path + resource_id |
next | Next page | base_path + "?limit=" + L + "&offset=" + (O + L) |
prev | Previous page | base_path + "?limit=" + L + "&offset=" + (O - L) |
Hands-on Exercise
- Open your code for the
/v1/taskscollection endpoint. - Update the controller to calculate the
nextandprevoffset values. - If
offset + limitis greater thantotal, setnexttonull. - Return the new
linksobject in your response envelope.
Common Pitfalls
- Hard-coding Domains: Never include the full URL (e.g.,
https://api.myapp.com/...) in your links if you can avoid it. Use relative paths starting from the version prefix. This makes your API portable across staging and production environments. - Ignoring Nulls: If there is no "next" page, don't omit the link entirely—set it to
null. This allows the client to reliably checkif (links.next)without worrying about key existence. - Over-linking: Don't turn your response into a map of every possible action. Stick to navigation and canonical identity to avoid cluttering your responses.
Frequently Asked Questions
Q: Should I use _links or just links?
A: Both are common. Use _links if you are following the HAL (Hypertext Application Language) specification, but links is perfectly acceptable for clean, custom REST APIs.
Q: Does this replace my documentation? A: No. While links make the API discoverable, documentation is still required to explain the request bodies and authentication requirements.
Recap
We've implemented "self" links for individual resources and navigation links for collection pagination. By including these links, you’ve made your API self-describing and significantly more resilient to future changes in your URI structure.
Up next: We will discuss how to implement request logging and monitoring to track how your API is being used in production.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.


