REST-ish URI design for multiple dependent resources

I am trying to create a web service based on REST-ish to interact with the animal management system for animals that I am working on.

To explain the problem in detail, I have a collection of farm animals . Each animal has its own information, such as name, identification number, breed age, etc. Therefore, I would suggest that a URI, like the following:

/animals <- retrieve list of animals /animals/{animal-id} <- Retrieve only one animal /animals?breed=sheep <- Search/query 

The problem arises when I try to associate other dependent resources with each animal. An animal can have a collection of weight information, as well as what I call comments (observations made for a particular animal). Each of them depends and exists only for one specific animal, but it is a resource that I want to access.

The simplest IMO approach would be to invest resources in animal URIs:

 /animals/{animal-id}/weights /animals/{animal-id}/comments 

However, I see the need for direct access and requests for weights and comments without reference to the animal. Examples of use would be to obtain the most recent (or total) weight (s) of all animals of a particular breed ...?breed=sheep Breed ...?breed=sheep or even return weights / comments to select an individual animal identifier ...?animals={ID1},{ID2},{...} Animals ...?animals={ID1},{ID2},{...} .

Further complications arise when I want to add one comment to several animals at once. (please excuse my submission of POST and JSON)

 POST .... { "comment":"Animal moved to paddock B", "animals":[{id1}, {id2}, ...] } 

I understand that the obvious solution to this problem would be GET and POST (for example) for each animal that I wanted to get / change. I would rather not do this, though, since in the end I want this service to be accessible from mobile devices, and therefore reducing the number of calls seems reasonable.

I believe web standards allow CSV in a URI, so something like this might work,

 /animals/{id1},{id2},{..}/weights 

But I expect cases where ten (and) animals may need a link right away (or requested), and this will lead to a messy and unfriendly URI.

My current perceived decision is to set weights and comments as my own resource, which allows me to directly access them and request them

 /weights /weights/{weight-id} /weights?breed=sheep 

and even send directly to the collection

 POST /comments { "comment":"Animal moved to paddock B", "animals":[{id1}, {id2}, ...] } 

But what would return /animals/{animal-id}/weights ? Is this even necessary, or would I just link the link to the /weights?animal={animal-id} resource myself? But is it possible to refer to the requested resource?

Am I doing one redundant or just providing a "different" way of accessing information?

Is there something I'm doing wrong, can I let my database influence my service model, or am I just not grabbing the point completely?

I am new to this and have read several conflicting arguments regarding these issues, and therefore I am completely confused about what works best for my requirements.

Thanks!

+4
source share
2 answers

It would be better to define top-level resources for your other objects if you want to address them as such ( /weights , /comments , etc.). You can then use POST for these endpoints in batch mode.

 POST /comments { "animals" : [ {"id" : 1}, {"id" : 2}, {"id" : 3}, {"id" : 4}, ], "commentText" : "Sent to Hamburger Hamlet" } 

Please note that including long identifier lists in the URL is not a good design for several reasons, including that most browsers and HTML proxies have restrictions on the length of the URL (a good rule is to try to keep the length of the URL in 2083 characters in length or less).

+3
source

I had similar problems, but in the end we were able to eliminate the difficulties that you get by having certain URL namespaces (so to speak) for different types of users using the API.

For example, it could be a farm worker client application that will perform your actions / weights / comments (POST, PUT, DELETE, etc.) that you describe so that you can keep your functionality clean with:

 /farmworkers/comments /farmworkers/weights 

And save the URL /animals/{animal-id}/weights in some other namespace.

Another thing to consider is embedding resources using something like the HAL format (http://stateless.co/hal_specification.html), which can allow you to embed multiple animal resources in a request, etc. Hope this helps.

+1
source

All Articles