views:

197

answers:

3

Let's assume that I have stores, shelves in a store, and products on a shelf. So in order to get a list of products on a shelf in a store, I'd use the following request:

GET http://server/stores/123/shelves/456/products

From here, how would I get an individual product? Should I use:

GET http://server/products/789

Or:

GET http://server/stores/123/shelves/456/products/789

The first method is more concise, since once you get a list of products, you don't really care which store it belongs to if you just want to view the details for a particular product. However, the second method is more logical, since you're viewing the products for a specific shelf in a specific store.

Likewise, what about a PUT/DELETE operation?

DELETE http://server/stores/123/shelves/456/products/789

Or:

DELETE http://server/products/789

What would be the correct way of designing a schema for a tree hierarchy like this?

P.S. If I'm misunderstanding something about the REST architecture, please provide examples on how I can make this better. There's way too many people who love to say "REST is not CRUD" and "REST is not RPC", then provide absolutely no clarifications or examples of good RESTful design.

A: 

Since products may be in several stores or several shelves (categories?), I'd have each product have a unique number regardless of its position in the hierarchy. Then use the flat product number. That makes the API more stable when some products are for instance moved in your store.

In short, don't add unneeded redundancy to your API. To get a shelve list a store ID is enough, for a product list a shelve ID is enough... etc.

Lucero
A: 

it seems like you are trying to build many different use cases, but everything is getting built into one super service. It would be better to break it out.

http://server/product_info/123123 or http://server/product_info?product=123123
http://server/product_inventory?store=123&shelf=345
then you can also support:
http://server/product_inventory?store=123

then PUT and DELETE makes sense for changing inventory or adding a new product.

mlathe
What about in the case of a POST? For example, if I'm adding a new product to a shelf, I wouldn't want to do something like `POST http://server/product_info/123?shelf=456`.
Daniel T.
A: 

Don't design a REST api based on an URL structure. Here is how I think you should go about designing a REST api.

Trying to define a REST interface without discussing what links will be contained in what resources is like discussing an RPC interface and ignoring parameters and return values.

Darrel Miller
Thanks for the link. We're only using a web service to allow an iPhone to download and upload data to a server (all internal), so it looks like what we want is RPC instead of REST (discoverability is not a concern).
Daniel T.
This is absolutely correct.
Wahnfrieden
Daniel T: there are still advantages to using REST. It will make your client more flexible to changes on the server. Then your server can manage its URI space however it likes without breaking clients.
Wahnfrieden
For this application, we're only interested in sending data back and forth betwen an iPhone and server, both of which are only used internally. The cost of constructing objects that contain URL links and summaries, and implementing a way to parse this data on the iPhone, is more costly than saying "Here's the API, grab data like this".
Daniel T.
As long as you accept that you have to update and re-deploy all your clients whenever you update your server in a way that changes its URI space, then RPC is fine here. No need to over-architect things after all. However, please do not erroneously refer to it as REST then, since too many people already misappropriate the term and it's become quite confusing.
Wahnfrieden