I'm designing a RESTful API that is using the HTTP status codes and verbs as key components in communicating.
On the religious level it's on the zealot side of RESTafarian.
Rule of thumb for deciding HTTP status codes has been this graph, or similar resources.
GET /api/documents/1
- 401
User has not logged inGET /api/documents/1
- 200
User has permissionGET /api/documents/1
- 403
User does not have permissionDELETE /api/documents/1
- 204
Users has permissionDELETE /api/documents/1
- 403
User does not have permissionGET /api/documents/2
- 404
Users permission irrelevant, resource does not existDELETE /api/documents/2
- 404
Users permission irrelevant, resource does not existDELETE /api/documents/1
- 404
Users has permission, resource already deletedDELETE /api/documents/1
- 404
Users does not have permission, resource already deletedGoals:
In this situation there is a lot of different status code to chose from ( 404, 403, 410, 405) and in my case I went with 403 on a existing resource if its not yours to not clear the cache, and 404 on all non existing resources so to tell the clients to wipe that data.
But I do not like the switch from 403 to 404 on resources that are not yours.
I'm interested to hear from others how you solved this use-case, or in general what status codes you feel appropriate to send in all invalid DELETE calls, since I deem that as one of the hardest to be concise with.
(A lot of REST discussions and answers on the internet in it whole are just "Throw a 400 bad request, no one cares anyway", I do not have a problem that needs a quick fix or a pragmatic hack. Thanks)
For a DELETE request: HTTP 200 or HTTP 204 should imply "resource deleted successfully". HTTP 202 can also be returned by either operation and would imply that the instruction was accepted by the server, but not fully applied yet.
Rationale: DELETE should be idempotent. If you return 404 on a second DELETE, your response is changing from a success code to an error code. The client program may take incorrect actions based on the assumption the DELETE failed.
200 OK - This is the most appropriate code for most use-cases. 204 No Content - A proper code for updates that don't return data to the client, for example when just saving a currently edited document. 202 Accepted - If the update is done asynchronous, this code can be used.
The HyperText Transfer Protocol (HTTP) 202 Accepted response status code indicates that the request has been accepted for processing, but the processing has not been completed; in fact, processing may not have started yet.
General pointer: In case a resource exists but a user is not authorized to perform operations on it, you should return 401 over 403:
401 Unauthorized
Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
and
403 Forbidden
The request was a valid request, but the server is refusing to respond to it. Unlike a 401 Unauthorized response, authenticating will make no difference.
See also Correct HTTP status code when resource is available but not accessible because of permissions
I went with 403 on a existing resource if its not yours to not clear the cache, and 404 on all non existing resources so to tell the clients to wipe that data.
As pointed out earlier, 401 should be used instead of 403. 404 is ok to return if you just want to say "sorry, resource not found". If you however want to say "resource was here but it's not anymore and never again will be" (this appears to be the case in your situation) you can return 410:
410 Gone
Indicates that the resource requested is no longer available and will not be available again. This should be used when a resource has been intentionally removed and the resource should be purged. Upon receiving a 410 status code, the client should not request the resource again in the future. Clients such as search engines should remove the resource from their indices
To summarize, this is how I would implement it in your case. The changes I made are in bold.
GET /api/documents/1
- 401
User has not logged inGET /api/documents/1
- 200
User has permissionGET /api/documents/1
- 401 User does not have permissionDELETE /api/documents/1
- 204
User has permissionDELETE /api/documents/1
- 403 User does not have permissionGET /api/documents/2
- 404
Users permission irrelevant, resource does not existDELETE /api/documents/2
- 404
Users permission irrelevant, resource does not existDELETE /api/documents/1
- 410 User has permission, resource already deletedDELETE /api/documents/1
- 401 User does not have permission, resource already deletedFor the last one, you can return 401 if you do not want the unauthorized user to know that there was a resource that has already been deleted. If you don't care you can return 410. That is for you to decide.
I do not like the switch from 403 to 404 on resources that are not yours.
It's perfectly fine to return different status codes depending on what the situation is.
I hope this helps you out a bit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With