So, there are two questions here: 1) what is the intended behavior? 2) what does the spec actually say at the moment?
Intended Behavior
The intended behavior is that GET /articles/1
is a 404 if an article with that id does not exist.
Hereâs the reasoning/backstory:
A relationship is, conceptually: 1) a collection of resource identifier objects with 2) an associated type (to-one or to-many). In a to-many relationship, the contents are always serialized as an array; in a to-one relationship, theyâre serialized as null or a single identifier object.
The related
url represents a projection of the relationship, where each resource identifier object is mapped to the resource object it identifies. This result retains the same rules for communicating the relationship type â a to-one relationship gets projected to null or a single resource, and a to-many gets projected to a (possibly empty) array of resource objects.
So, if a resource object includes a relationship with a related
url, then that related url represents a set of related resources that does conceptually exist, but might be empty. If it is empty, the server should return data: null
in this case, rather than 404, precisely to tell the client that the related
collection does at least exist. (As you guys have pointed out, this is a useful distinction.)
Communicating âthis exists but is currently emptyâ is the only reason the spec introduces the data: null
response. When something simply doesnât exist at the time of the request, 404 is appropriate.
Spec text
When the spec talks about a URL that âmight correspond to a single resource, but doesnât currentlyâ, itâs trying to get at this idea of âthe thing exists but doesnât currently have any contentsâ.
I agree with Michael that the spec doesnât actually say that, but my strong suspicion is that many implementations have interpreted 404 as the correct response anyway. I know thatâs how my implementation has always behaved, I assume itâs how Scottâs behaves, and I imagine itâs how @dgebâs behaves as well.
Unless a strong majority of implementations use the 200 OK interpretation (which I doubt), I have no problems clarifying the spec text to reflect the 404 behavior. At the end of the day, our backwards compatibility promises are about maintaining interoperability, so, if implementations in practice are already divided on this, clarifying the text doesnât make things less interoperable.
Iâd also point out that, if we were instead to double down on Michaelâs reading of the spec, it would lead to some pretty bizarre behavior. In particular, JSON:API gives a server the flexibility to assign urls to resources however it wants, so, in theory, almost any url âmight correspond to a single resourceâ. Therefore, reading the text as Michael suggests would make it impossible for a server to return a 404 at a clearly non-existent resource. For example, every JSON:API server would have to have GET /xcvcxtfien
return a 200 Ok
with data null. I donât think thatâs plausible/something we want.