2

I'm working on a REST api following the JSON api specification and I'm struggling with the "no data" responses (described here).

A server MUST respond with 404 Not Found when processing a request to fetch a single resource that does not exist, except when the request warrants a 200 OK response with null as the primary data (as described above).

The "described above" refers to the previous section of the specification :

A server MUST respond to a successful request to fetch an individual resource with a resource object or null provided as the response document's primary data.

null is only an appropriate response when the requested URL is one that might correspond to a single resource, but doesn't currently.

I don't understand when I need to return a HTTP 404 Not Found and when I need with HTTP 200 OK with {"data":null}.

For example, if I have the following URL :

http://example.org/users/52

This URL is correct, but the User referenced by the ID 52 doesn't exist.What is the correct response ? A 404 or a 200 data: null ?

  • Return 404 when your underling code would throw a 'not found' exception, return null when your code would return null – Ewan Dec 27 '15 at 11:12
  • A valid resource with null data is different to a resource that doesn't exist. An example would be a weather forecasting api that accepts 21/Dec/2034/weather as a valid resource but has no data for that resource. You wouldn't return 404 because the resource technically exists. Personally I hate this idea, I think you should always return some semantically meaning information, "null" as a data is very unhelpful. – Cormac Mulhall Dec 30 '15 at 14:02
4

If the user 52 doesn't exist, return HTTP 404. Returning HTTP 200 is misleading.

Think about it from the point of view of the client. Would the following dialog make sense to you?

Client: please, I want to know something about user 52.
Server: of course (HTTP 200). What do you want to know?
Client: I want to know the basic information about the user.
Server: There is no information whatsoever about this user; I don't even know what are you talking about.

The case where you could use HTTP 200 with null is when you don't have information about a part of the entry being requested. Imagine a case where the users have a purchase history, unless they registered very recently and haven't been approved yet (and cannot order anything). For an ordinary, approved user, the response will be:

HTTP/1.1 200 OK

{
    "id": 51,
    "name": "Laura Norman",
    "purchase-history": [
        { ... },
        ...
    ]
}

Instead, the user 52 doesn't have a purchase history:

HTTP/1.1 200 OK

{
    "id": 52,
    "name": "David Johnson",
    "purchase-history": null
}

This is semantically different from an empty sequence. "purchase-history": [] means that the user has a history, but haven't purchased anything yet. A null has a very different meaning.

  • How di you distiguish between users/52 and usres/53 – Ewan Dec 27 '15 at 11:19
1

Don't just look at it from the point of view of the API, but also from the point of view of the client.

If I request http://example.org/users/52 as the client, there are a few things that are not unexpected: Total failure without even getting a status code (no network, https refused if it was https), status 401 or 500 (500 is always possible if the server is confused), but the two essential possibilities are that either the user does not exist, or that the user exists. And both would be handled by the client code in very different ways. That's way I would hope for either status 200 + the information that I want, or for status 404 (not found).

It's different if I have a search where any number of items could be returned, including zero, one, or many items. In that case I'd expect status 200 and an array of items, which might be an empty array. Status 404 I would expect if the API didn't ever get as far as searching. For example if I search for all purchases of user 52 from March to July, I'd expect status 404 if the user doesn't exist, and 200 if the user exists.

I don't know if the misspelling in a comment about usres/53 was intentional or not. This should give a status 404, or perhaps 400. In practice, the client isn't going to ask for that URL (once it is debugged and working properly). It is quite common for APIs to return a response together with the status, and in that case a response that clearly indicates that "usres" is not valid at all would be useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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