Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle nested resources in Web API ("REST") when not found?

Let say I have a resource Person and on a person I have a nested resource SomeResource. Which status code should be returned and why in the following scenarios?

/Person/1/SomeResource (SomeResource does not exist)
/Person/1/SomeResource (Person does not exist)

I think that 404 should be used in both scenarios but not everyone agrees and I would like to know why. You could argue that Person is the underlying resource and SomeResource is just a "property" on that resource and the request to SomeResource should therefor return nothing in the first scenario but 404 in the second scenario. I think that might be an option, but I still like 404 more. Another scenario that I don't like at all is to return 500 with an error description, that was an alternative I heard in the discussion as well but that forces the consumer to program against exception which I don't like. 500 for me means that something went wrong and you can't really do anything about it.

The problem is that the argument was that you don't know why you got a 404 if you got it, was it because of that the Person didn't exist or because of that the SomeResource didn't exist.

UPDATE 1: Maybe I should break out SomeResource to a separate resource like

/SomeResource/1

which returns a response like {data: {the data}, person: {person data}}, and this only returns 404 if both are missing but if the data is missing a 200 is returned with empty data.

UPDATE 2: I think I figured out which status code to use and it is 400 for when the person is not existing since I at that point considering it a request you should never have done, that is, a bad request. When SomeResource is missing I would go for 404 since the Person did exist but the nested resource was missing.

like image 969
Tomas Jansson Avatar asked Nov 13 '22 02:11

Tomas Jansson


1 Answers

It may be helpful to remember that a given URI is intended to identify at single "resource". Semantically, a URI structure does not support the concept of "nested" resources. It seems you have two resources: Person & SomeResource in your scenario where SomeResource has a relation of some sort with Person. You could try a structure like this to represent this relationship:

GET /person/1

{
    name: "Some Value",
    someResource: {
        "Href": "http://yourSite.com/someresource/123",
        "Title": "Get some resource for this specific person"
    },

    // other key/value pairs as appropriate...
}

This way you are not overloading the 400 & 404 with application specific meanings. If the client has received a valid Person result, it would simply invoke the SomeResource href and would receive the appropriate 404 or not depending on SomeResource 123 existing. If the Person URI does not exists, invoking it would appropriately return 404 since it does not exist.

like image 127
Sixto Saez Avatar answered Apr 01 '23 21:04

Sixto Saez