Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST-API, proper HTTP status code for invalid DELETE

Tags:

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 in
  • GET /api/documents/1 - 200 User has permission
  • GET /api/documents/1 - 403 User does not have permission
  • DELETE /api/documents/1 - 204 Users has permission
  • DELETE /api/documents/1 - 403 User does not have permission
  • GET /api/documents/2 - 404 Users permission irrelevant, resource does not exist
  • DELETE /api/documents/2 - 404 Users permission irrelevant, resource does not exist
  • DELETE /api/documents/1 - 404 Users has permission, resource already deleted
  • DELETE /api/documents/1 - 404 Users does not have permission, resource already deleted

Goals:

  • Consistency in usage
  • Not to expose private information through errors
  • Proper use of status codes for client or middle layer caches
  • Fail early, keep lookups to a minimum

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)

like image 990
Cleric Avatar asked May 06 '14 06:05

Cleric


People also ask

What HTTP status code for delete?

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.

Should a delete return a 404?

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.

Should Put return 200 or 204?

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.

What is a 202 status code?

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.


1 Answers

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 in
  • GET /api/documents/1 - 200 User has permission
  • GET /api/documents/1 - 401 User does not have permission
  • DELETE /api/documents/1 - 204 User has permission
  • DELETE /api/documents/1 - 403 User does not have permission
  • GET /api/documents/2 - 404 Users permission irrelevant, resource does not exist
  • DELETE /api/documents/2 - 404 Users permission irrelevant, resource does not exist
  • DELETE /api/documents/1 - 410 User has permission, resource already deleted
  • DELETE /api/documents/1 - 401 User does not have permission, resource already deleted

For 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.

like image 58
Tim Avatar answered Sep 25 '22 18:09

Tim