Card 05/ 11

ConceptDifficulty: Intermediate2 min

Nested Resources, and When to Stop Nesting

/authors/7/books reads well; /authors/7/books/12/reviews/3/likes is a path nobody can use.

Nesting a collection under an item, as in /books/12/reviews, says the reviews belong to that book and lists only them. One level of nesting usually reads well; deeper paths force the client to know every parent's id to reach a child. Anything with its own identifier should also have a short top-level path.

The same like on a review, reached by a deep path and by a flat one

Deepfour parents

GET /authors/7/books/12/reviews/3/likes/9. The client needs the author, book and review ids to reach one like. If the book gains a second author, the like has two paths, and which is right is unclear.

Flatone parent at most

GET /reviews/3/likes lists a review's likes; GET /likes/9 reads one. The client needs only the id it holds, and each like has one path.

Nest for ownership. A sub-collection fits when the child cannot exist without the parent and is usually listed through it: an order's items, a book's reviews. Creating through the parent, POST /orders/42/items, also records the relationship without a field in the body.

Stop at one level. /orders/42/items is clear; /customers/7/orders/42/items adds a customer id the server could look up from the order. Every extra parent is something the client must have and can get wrong. If the server must check that order 42 belongs to customer 7, it can do so from its own data.

Give independent things a top-level path. An author exists without any book, so /authors/7, not /books/12/authors/7. A resource that might move between parents, such as a task between projects, needs a path that does not change when it moves.

Filter instead of nesting deeper. "Reviews of book 12 written by user 5" is GET /books/12/reviews?author=5, not another path segment.

So nest one level where a parent owns its children, and reach everything with its own identity by its own short path.