Reputation: 4342
I am trying to find the proper status code to return, here's what I have in mind so far:
GET /api/documents/1
- document exists, user has access - 200 OKGET /api/documents/2
- document exists, user does not have access - 403 ForbiddenGET /api/documents/3
- document does not exist (cannot check if has access or not) - 404 Not Found? 403 Forbidden?GET /api/documents/a
- id is invalid (should be a number) - 400 Bad Request? 404 Not Found? 403 Forbidden?The problem with my backend (using MongoDB) at the moment is that the first thing I do is check if the user has access to a document by checking it against a list of document IDs he has access to. If the document_id is not found in the list, 403 Forbidden is automatically returned. This helps me to avoid fetching the document from the db first to see if the user can access it.
I am not sure what would be the best practise here - should I pursue better HTTP status codes (and thus creating extra db requests) or would 403 Forbidden work for the last 2 cases (3 and 4) as well?
Upvotes: 7
Views: 6494
Reputation: 7324
I'd suggest 404 for both #3 and #4.
1. GET /api/documents/1 - document exists, user has access - 200 OK
200 is appropriate.
2. GET /api/documents/2 - document exists, user does not have access - 403 Forbidden
403 is appropriate.
3. GET /api/documents/3 - document does not exist (cannot check if has access or not) - 404 Not Found? 403 Forbidden?
404 is appropriate here since the document does not exist at the specified URI.
4. GET /api/documents/a - id is invalid (should be a number) - 400 Bad Request? 404 Not Found? 403 Forbidden?
404 is still appropriate here since no resource exists at the specified URI. For reference, a 400 refers to malformed syntax, but the URI and request are perfectly valid syntactically; it's just that there isn't a corresponding resource available on your server.
In general, you should think first about the API and following standard HTTP approaches. Whether or not this requires another internal database request is an implementation detail. I'd suggest avoiding premature optimizations, especially those that will have such a direct impact on your clients.
Upvotes: 11
Reputation: 71384
I would say use the HTTP codes as intended for scenario #3, use 404 (as the resource is not found but the user would have had access permissions if it was), for scenario #4 use 400 (as it is indeed a bad request).
The well help your implementing client understand what is exactly going wrong. Particularly for 404, which in a lot of systems would come up in normal operation (i.e. querying for login credentials or something similar), the client may need to understand the exact reason their request wasn't fulfilled.
I fail to see how returning the proper status code would result in more DB requests. You could still return the 403 for the legitimate 403 use case.
Upvotes: 1