7. Including Related Data
7. Including Related Data
Fetching a resource and then issuing a second request for every related object it references leads to chatty APIs and slow client-side loading. Providing a mechanism to include related data in a single response solves this without permanently bloating every payload.
The Principle: Keep the Base Payload Lean
By default, return only the fields that belong directly to the requested resource. Do not eagerly embed related objects. This keeps responses small, predictable, and fast.
Opt-In Expansion with include
Let clients request related resources by passing an include query parameter listing the relationships they want:
GET /posts/100?include=author
GET /posts/100?include=author,category
GET /posts/100?include=author,comments
The server embeds the requested relations into the response:
{
"data": {
"id": 100,
"title": "Designing Better APIs",
"author": {
"id": 7,
"name": "Jane Smith"
},
"category": {
"id": 3,
"name": "Engineering"
}
}
}
Nested Expansion
Some APIs support dot-notation to expand relations one level deeper:
GET /orders/42?include=items,items.product
This returns each order item together with its associated product, all in one request. Be cautious with deep nesting — it can lead to large payloads and expensive database queries. Document any depth limits clearly.
Guidelines
- Whitelist the allowed relationships. Do not let clients expand arbitrary paths; only support the relations you have explicitly designed and tested.
- Document every supported relation in your API specification so clients know what is available.
- Set a limit on the number of relations that can be requested in a single call to prevent abuse or accidental over-fetching.
- Cache-friendly by default. The base resource URL without
includeparameters remains cacheable; expansions can be treated as separate cache keys.