4

I feel as if i am over-thinking this, but with a RESTful API design with resources being themselves resources of something how should these 'typically' be accessed?

Of course, an acceptable answer is 'it depends', but i am trying to understand what is usually what people might expect, and then also what is easiest to reason about during implementaiton.

An example, we have houses and rooms within those houses..

Fetch all the houses, or get a single specific house info:

GET ../v1/houses <--- [] of house info
GET ../v1/houses/{houseId} <--- specific house info

So far so good, then if i want all the rooms regardless of house, a specific known room, or all the rooms of a specific type:

GET ../v1/rooms <--- [] of all rooms, users current want this
GET ../v1/rooms/{roomId} <--- specific room, implicitly in a specific house
GET ../v1/rooms?roomType=bathroom <--- all bathrooms in all houses

Q: If these are implicitly part of a house (and you cannot reasonably have a room without a house) should they also return information about the "parent" resource too? I think yes.

If however a user wants all the rooms in a specific house should we do a)

GET ../v1/houses/{houseId}/rooms <--- sub-resource room info

or require two-step b)

GET ../v1/houses/{houseId} <--- get detail of the house inc. roomId values
GET ../v1/rooms/{roomId} <--- query them all

or even filter c)

GET ../v1/rooms?houseId={houseId}

Q: You can't pass a body with a GET, so which is the most acceptable solution? Q: Bonus points for what to really do when needing all the rooms across more than a single house. This feels very non-RESTful:

GET ../v1/rooms?houseId={houseId},{houseId}
GET ../v1/rooms?houseId={houseId},{houseId}&?roomType=kitchen

I guess this could be one of those situations whereby it's your own preference, but happy to hear other peoples thoughts?

Ty.

3 Answers 3

5

To begin: "sub-resources" aren't really a thing in REST. Resources are "information that can be named" (Fielding, 2000) or "whatever might be identified by a URI" (RFC-3986).

So /houses and /houses/1 are each "resources". The fact that one identifier is hierarchically subordinate to the other doesn't have any meaning to general purpose REST components. You could just as easily substitute in /b4b065c4-b4ee-4a1c-b07f-c7a133af34fb and /2181774a-0a9e-489c-a7e7-7623597ca2b1; the machines don't care.

(Humans, on the other hand, tend to care quite a bit. And since the machines don't care at all, we ought to choose designs that make things easier for some of the humans we care about.)

If we want to communicate a relationship between these two resources, we do it with a link relation. For instance, we might choose to communicate that /houses/1 is an item in the /houses collection, or that /houses is the collection for item /houses/1. We'd normally do that using the item and collection link relations, currently defined by RFC 6573.

Also note: there's no rule that says that the "information that can be named" has to be unique to a particular resource. In fact, it's common for different resources to overlap to the point that their representations are identical (Fielding, 2000 includes an example of this).

So yes, if you want to return information specific to a room as part of the description of the house, or information about the house as part of the description of the room, that's fine.

And if you want to not do that, and only have the resources link to one another, that's also fine.

If a client wants a different collection of information than the ones you are already providing, then you can just create another resource with the information you are willing to provide. Ta-da.

Note: you aren't required to twist yourself into knots trying to align the names of your resources with the names of your data entities. /the-report-bob-wanted is a perfectly fine resource name for a perfectly fine resource. If you have a whole family of resources like that, then choose names that are easily computed from URI Templates.

This feels very non-RESTful

It's fine. It may help to review Stefan Tilkov's 2014 talk.

0

Curiously the answer to this is the same answer I usually do for object-orientation related questions. That is: It depends on the behavior.

Unless you are a database that just serves dumb data (in which case just use an existing database), you probably want to support some functionality. The structure / design of your resources should be based on the workflow(s) of the client(s) you want to support. It should be designed the same way web-UIs are. As simple as possible, leading / navigating the user through your workflow to achieve some function.

Data, URIs, sub-resource relations, parameters, etc. are all completely irrelevant when designing an API. The exact same way URIs, data, etc. are irrelevant when you try to purchase something off amazon.

Summary: Think about the behavior / functionality you want to support, design to support those in the easiest to use way possible.

0

As Robert states in his answer, it depends. Design to your requirements. REST says very little about such details, intentionally. However, it does make one strong statement along these lines, with the (terrible) acronym HATEOAS: Hypermedia as the Engine of Application State. REST states that all resources are accessible via links from the root application. Thus, if you know the URL of an application, it is completely accessible via exploration of these links.

Thus REST is quiet on whether it should be GET ../v1/houses/{houseId}/rooms or GET ../v1/houses/{houseId} followed by a number of GET ../v1/rooms/{roomId}. But it does state that the answer to that question should be accessable via hypermedia from your application URL. It may take following many links, but eventually you should give the client the answer to that question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.