RESTful API – Representing Absence of a Resource

rest

Imagine an API to identify whether a person has selected their spirit animal. They can only have zero or one spirit animals.

Currently:

/person/{id}/selectedSpiritAnimal

when they have selected an animal returns http 200 and {selectedAnimal:mole}

but when they have no selection it returns http 404.

This makes my spirit animal unhappy as we're representing a valid domain concern – having not yet selected a spirit animal – as an HTTP error.

Plus, as a business – erm Sprit-Animal-Hampers-R-us – we want to know when someone has no selection so we can prompt them.

What's a better response here:

HTTP 200 and {selectedAnimal:null}

or even more explicit

HTTP 200 and {selectedAnimal:null, spiritAnimalSelected: false}

Or is it better to return a 404? Since much like this image has not yet been uploaded when viewing an image online would be a 404. this person has not selected a spirit animal might be a 404


This question has been proposed as a duplicate but that question addresses an otherwise valid URL being requested when the application has been configured to not allow the change that URL represents.

Whereas here I'm looking at how one represents a resource where the absence of the resource is meaningful. I.e. it is valid for the client to request the URL and the response is you have successfully requested the resource which represents an absence of a thing.

So this isn't 'business logic' but rather a circumstance where the absence of a thing has meaning (it may be as many of my colleagues are arguing that 404 is still correct) but I'm not sure how to map that to the spec.


Very difficult to pick an answer. I've changed my mind multiple times over the conversation here and the one ongoing at work.

The thing that settles it for me here is that the spec says that a 4xx is when the client has erred. In this instance the client has been told to expect a response from the selectedSpiritAnimal url so has not erred.

The consensus amongst my colleagues is that this is a symptom of a bad API design

It would probably be better that we simply request /person/{id} and that returns a set of link relations for the person… then if you aren't given the /selectedSpiritAnimal link (when a person has no selection) but you call it anyway then a 404 makes sense. Or that you implement partial responses and let /person/{id} return a more full document unless the client requests a subset of the data

Best Answer

HTTP 4xx codes are probably not the right choice for this scenario. You state that having zero spirit animals is a valid state, and the API route person/{id}/selectedSpiritAnimal will account for whether person id does or does not have one.

HTTP 4xx responses are reserved for the situation when a client has done something incorrect in the request (see w3's archive of the original spec). But the client is making a valid request, whether or not person id has a spirit animal.

So I lean toward the second solutions using a properly formatted JSON body in the response and an HTTP 2xx code.

Now if you get such a request and it turns out person id does not exist, a 4xx code makes more sense.