REST collections, good practice to do: GET api/CollectionA/<collection id>/CollectionB?

collections, rest

Solution

Objective: We want to get the Reviews for all of the Products

Basically, `GET /api/products/<id>` should return a `product`, and `GET /api/products/<id>/reviews` should return all `reviews` for a given `product`.

If you want to fetch all `products`, you will use `GET /api/products`. As you consider both `reviews` and `products` as resources, I recommend you to expose all `reviews`:

GET /api/reviews

But you probably want `products` with their `reviews`. That would mean fetching some products using `/api/products` (and a set of filters for example) and expanding the result set with `reviews`. This `expand` term comes from the OData protocol: http://www.odata.org/documentation/uri-conventions#ExpandSystemQueryOption.

You could do:

GET /api/products?$expand=reviews

GET /api/products?filter=foo&$expand=reviews

This URI means: "identifies the collection of `products` as well as each of the `reviews` associated with each `product`.

Problem

I need to be able to grab a collection based on a collection of objects. For this, I'm considering a couple of approaches, but am not sure which one makes the most sense, so I'll post them both. If there is a better way that I may not have considered, then please feel free to post your suggestion(s) :) For example, I'll use Products and Reviews (which are reviews of products) as resources. Objective: We want to get the Reviews for all of the Products Approach A: ``` POST api/Products { json: filters, limits, etc } // returns api/Products/<id> GET api/Products/<id>/Reviews { json: filters, limits, etc } // returns json array // ... of reviews present in products // id in this case would refer to the collection, which would be cached ``` Approach B: ``` GET api/Reviews { json: filters } // returns json array of reviews, but needs to // ... have either all of the product ids passed as an array (not practical with // ... huge collections), or needs to have all of the api/Products filters passed, // ... in which case making the code unDRY ``` Approach C: ``` GET api/Reviews { json: filters: { products: 'api/Products?filters' }... // is this reasonable? ``` Thanks in advance for any help, and apologies if this question is noob, I'm still new to REST Approach D: ``` access individual products GET api/Product/<id> access collection of products: POST api/Products?filters=stuff.. GET api/Products/<id> access collection of products' reviews POST api/Products/<id>/Reviews?filters=stuff GET api/Products/<id>/Reviews/<id> ... this would thus allow us to cache the result easily, does this seem reasonable to you? ```

Original source