My RESTful service includes a resource representing an item ACL. To update this ACL, a client does a PUT
request with the new ACL as its entity. On success, the PUT
response entity contains the sanitized, canonical version of the new ACL.
In most cases, the HTTP response status code is fairly obvious. 200
on success, 403
if the user isn't permitted to edit the ACL, 400
if the new ACL is malformed, 404
if they try to set an ACL on a nonexistent item, 412
if the If-Match
header doesn't match, and the like.
There is one case, however, where the correct HTTP status code isn't obvious. What if the authenticated user uses PUT
to remove themselves from the ACL? We need to indicate that the request has succeeded but that they no longer have access to the resource.
I've considered returning 200
with the new ACL in the PUT
entity, but this lacks any indication that they no longer have the ability to GET
the resource. I've considered directly returning 403
, but this doesn't indicate that the PUT
was successful. I've considered returning 303
with the Location
pointing back to the same resource (where a subsequent GET
will give a 403
), but this seems like a misuse of 303
given that the resource hasn't moved.
So what's the right REST HTTP status code for "success, and thus you no longer have access"?
The HTTP 204 No Content success status response code indicates that a request has succeeded, but that the client doesn't need to navigate away from its current page.
HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: Informational responses ( 100 – 199 ) Successful responses ( 200 – 299 )
Prevailing theory is that the status is set to null and the statuscode set to -1 when the response object is constructed, and then something happens to the connection that means the request doesn't complete, so these defaults are never overwritten with real values.
A 200-level response means that everything is working exactly as it should. 200: “Everything is OK.” This is the code that is delivered when a web page or resource acts exactly the way it's expected to. 201: “Created.” The server has fulfilled the browser's request, and as a result, has created a new resource.
2 201 Created. The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field.
The HTTP 200 OK success status response code indicates that the request has succeeded. A 200 response is cacheable by default. The meaning of a success depends on the HTTP request method: GET : The resource has been fetched and is transmitted in the message body.
200 is the appropriate response, because it indicates success (as any 2xx code implies). You may distinguish the user's lack of permission in the response (or, if you don't wish to, 204 is fine). Status codes make no contract that future requests will return the same code: a 200 response to the PUT does not mean a subsequent GET can't return 403. In general, servers should never try to tell clients what will happen if they issue a particular request. HTTP clients should almost always leap before they look and be prepared to handle almost any response code.
You should read the updated description of the PUT method in httpbis; it discusses not only the use of 200/204 but indicates on a careful reading that returning a transformed representation in immediate response to the PUT is not appropriate; instead, use an ETag or Last-Modified header to indicate whether the entity the client sent was transformed or not. If it was, the client should issue a subsequent GET rather than expecting the new representation to be sent in response to the PUT, if for no other reason than to update any caches along the way (because the response to a PUT is not cacheable). Section 6.3.1 agrees: the response to a PUT should represent the status of the action, not the resource itself. Note also that, for a new ACL, you MUST return 201, not 200.
You're confusing two semantic ideas, and trying to combine them into a single response code.
The first: That you successfully created an ACL at the location that you were attempting to. The correct semantic response (in either a RESTful or non-RESTful scenario) is a 201 Created. From the RFC: "The request has been fulfilled and resulted in a new resource being created."
The second: That the user who executed the PUT does not have access to this resource any more. This is a transient idea - what if the ACL is updated, or something changes before the next request? The idea that a user does not have access to a resource of any kind (and this includes an ACL resource) only matters for the scope of that request. Before the next request is executed, something could change. On a single request where a user does not have access to something you should return a 403 Forbidden.
Your PUT method should return a 201. If the client is worried about whether it has access any more, it should make a subsequent request to determine it's status.
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