<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Relationships

Relationships

Resources reference each other: a book has an author, an author has many books. Plain REST gives you two bad defaults — embed everything (bloated responses) or return only IDs and force the client into follow-up requests. That second one is the network N+1 problem:

GET /books        → [{ id: 1, authorId: "a1" }, { id: 2, authorId: "a2" }, ...]
GET /authors/a1   → { name: "Fitzgerald" }
GET /authors/a2   → { name: "Orwell" }
...one more round trip per author

JSON:API handles this in two parts. First, every resource declares its relationships as type/id pairs plus links to fetch them:

{
  "type": "books",
  "id": "42",
  "attributes": { "title": "The Hobbit" },
  "relationships": {
    "author": {
      "data": { "type": "authors", "id": "7" },
      "links": { "related": "/books/42/author" }
    }
  }
}

Second, the client can ask for related resources in the same response with include. The result is a compound document: related records arrive in a top-level included array, each one appearing exactly once no matter how many books reference it.

{
  "data": [
    {
      "type": "books", "id": "42",
      "attributes": { "title": "The Hobbit" },
      "relationships": { "author": { "data": { "type": "authors", "id": "7" } } }
    }
  ],
  "included": [
    { "type": "authors", "id": "7", "attributes": { "name": "J.R.R. Tolkien" } }
  ]
}

One round trip, no duplicated author records, and the client stitches records together by type + id.

Return only IDs — N+1 round trips Client API server GET /books → [ids] GET /authors/a1 GET /authors/a2 GET /authors/a3 … 1 + N requests include=author — one round trip Client API server GET /books?include=author data + included (one response) 1 request
Returning only IDs forces one follow-up request per author (1 + N round trips). include packs the related records into a single compound response.

Exercise

Code challenge

Resolve a compound document

Given a JSON:API compound document (books in data, their authors in included), resolve each book's author and return { title, author } pairs. Fill in the top-level array the related records arrive in.