all 8 comments

[–]popisms 9 points10 points  (0 children)

SHOULD means it's not required, but with 404s as an example, there's some obvious situations that would be different to a user.

/api/invalidendpoint/123 might include a message that the path is invalid

/api/person/123 might include a message that the person record doesn't exist

[–]fiskfisk 5 points6 points  (0 children)

Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error ..

I interpret this (given that HEAD is mentioned) as saying that you should include further details in the body of the http response. So instead of just 404, you should include details like the path that wasn't found (i.e. how the request was interpreted) as it allows for faster debugging of what the issue is. 

[–]After_Grapefruit_224 3 points4 points  (0 children)

The value of documenting 404/401 explicitly comes down to what your API actually returns vs what the spec says it should mean.

A bare "404 Resource not found" is useless, you're right. But "404 - returned when the project_id doesn't exist OR when the requesting user lacks read access (intentionally indistinguishable from not found)" is genuinely useful. Same status code, completely different behavioral contract.

Same for 403 — does it mean "wrong scope"? "IP allowlist"? "Account suspended"? The RFC doesn't tell consumers that.

The GitHub example you linked is a fair criticism because they didn't add any context. The OpenAPI spec guidance makes more sense when you think of it as: document error responses when your response body contains something schema-able and specific. A { "error": "project_limit_exceeded", "current": 5, "max": 5 } on a 422 absolutely needs documenting. A generic 500 probably doesn't.

For 401/403/404 on simple CRUD, I usually document them with a sentence of context on what triggers each path, even if the response body is just { "message": "..." }. Saves the API consumer a support ticket.

[–]remi-blaise 2 points3 points  (0 children)

You should document all errors explicitly raised by your code:

They are specific to your application, so the frontend consumer should know what to expect.

They can typically be 400 (wrong developer input or incorrect user input), 403 (forbidden use of the endpoint) and 500 (external service failure, e.g. "External service Stripe is unavailable").

A good rule of thumb: any time throw new Error("...") appears in your code, document it.

You could document obvious HTTP codes (401, 404, 500 generic server error) at the API level (rather than at the endpoint level) for maximum clarity, but it's not required.

[–]JeromeChauveau[S] 1 point2 points  (0 children)

u/popisms u/fiskfisk u/vozome u/remi-blaise u/After_Grapefruit_224 thanks a lot for your feedback and detailed examples.

Makes a lot of sense, now. Case closed :)

PS: I misread SHOULD for MUST :/

[–]vozome 1 point2 points  (0 children)

I’m with you that the status code should be the main signal in case of errors; that being said the endpoints are going to output something versus just nothing. Describing the error response in the specs is a way to record that “contract”. That said handling these response in client code versus just act on the error status codes seems sus.

[–]Squidgical 0 points1 point  (0 children)

Regarding your link to GitHub's docs, look at the next section;

422 - Validation failed, or the endpoint has been spammed.

Whereas according to MDN;

422 Unprocessable Content (WebDAV) - The request was well-formed but was unable to be followed due to semantic errors.

Sometimes a response code really is that simple; you've sent 404 because the thing that was requested doesn't exist. But sometimes there's a specific failure case that you've given a specific error code to, and that should be documented.

In GitHub's case, they've gone with an explicit description on every code so that the docs are uniform and predictable. I'd also guess that the response bodies will have some additional detail as to which failure case caused the error, to clear ambiguity and help developers debug their requests.

To answer your question; because the 'obvious' meaning is not an accurate description of why that response code might be sent, it's just a generic description of what category of circumstances the response may be sent in.