I was wondering what people's opinions are of a RESTful PUT operation that returns nothing (null) in the response body.
14 Answers
The HTTP specification (RFC 2616) has a number of recommendations that are applicable. Here is my interpretation:
- HTTP status code
200 OKfor a successful PUT of an update to an existing resource. No response body needed. (Per Section 9.6,204 No Contentis even more appropriate.) - HTTP status code
201 Createdfor a successful PUT of a new resource, with the most specific URI for the new resource returned in the Location header field and any other relevant URIs and metadata of the resource echoed in the response body. (RFC 2616 Section 10.2.2) - HTTP status code
409 Conflictfor a PUT that is unsuccessful due to a 3rd-party modification, with a list of differences between the attempted update and the current resource in the response body. (RFC 2616 Section 10.4.10) - HTTP status code
400 Bad Requestfor an unsuccessful PUT, with natural-language text (such as English) in the response body that explains why the PUT failed. (RFC 2616 Section 10.4)
Note: RFC 2616 was the latest specification when this answer was written, but the RFC has since been superseded. When referring to any standard, it can be useful to verify that you are using the latest one.
20 Comments
200 for PUT, DELETE, or any other method. Did I miss something? Such as Mozilla becoming the boss of W3 and the IETF? ;) Or maybe they've just never heard of Postel's Robustness Principle.No response body needed in relation to a 200. In fact the response body is not mentioned at all in relation to a PUT. It only states If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.As opposed to most of the answers here, I actually think that PUT should return the updated resource (in addition to the HTTP code of course).
The reason why you would want to return the resource as a response for PUT operation is because when you send a resource representation to the server, the server can also apply some processing to this resource, so the client would like to know how does this resource look like after the request completed successfully. (otherwise it will have to issue another GET request).
20 Comments
If the backend of the REST API is a SQL relational database, then
- you should have RowVersion in every record that can be updated (to avoid the lost update problem)
- you should always return a new copy of the record after PUT (to get the new RowVersion).
If you don't care about lost updates, or if you want to force your clients to do a GET immediately after a PUT, then don't return anything from PUT.
Comments
I think it is possible for the server to return content in response to a PUT. If you are using a response envelop format that allows for sideloaded data (such as the format consumed by ember-data), then you can also include other objects that may have been modified via database triggers, etc. (Sideloaded data is explicitly to reduce # of requests, and this seems like a fine place to optimize.)
If I just accept the PUT and have nothing to report back, I use status code 204 with no body. If I have something to report, I use status code 200, and include a body.
Comments
I agree with the most voted answers above, but I would like to elaborate more on this.
REST is not a standard, therefore everyone could create and document it's own API as long as it fits the purpose and it is well documented, agreed and understood by the developers and consumers. What really matter is that the URLs identifies the exposed resources. I have been working with Http Rest APIs for years and I want to share what generally I use as standard approach, not because it's perfect, or "the rules of conduct", just because I found it easy to work with and explain to others.
Note that I am not mentioning hypermedia as this goes far beyond the purpose of the answer and I rather leave it out of scope, but if interested a good reading can be found in the OData specification.
Create
---------------------------------------------------------------------
Success - 201 Created - Return created object
Failure - 400 Invalid request - Return details about the failure
Async fire and forget operation - 202 Accepted - Optionally return url for polling status
Update
---------------------------------------------------------------------
Success - 200 Ok - Return the updated object
Success - 204 NoContent
Failure - 404 NotFound - The targeted entity identifier does not exist
Failure - 400 Invalid request - Return details about the failure
Async fire and forget operation - 202 Accepted - Optionally return url for polling status
Patch
---------------------------------------------------------------------
Success - 200 Ok - Return the patched object
Success - 204 NoContent
Failure - 404 NotFound - The targeted entity identifier does not exist
Failure - 400 Invalid request - Return details about the failure
Async fire and forget operation - 202 Accepted - Optionally return url for polling status
Delete
---------------------------------------------------------------------
Success - 200 Ok - No content
Success - 200 Ok - When element attempting to be deleted does not exist
Async fire and forget operation - 202 Accepted - Optionally return url for polling status
Get
---------------------------------------------------------------------
Success - 200 Ok - With the list of resulting entities matching the search criteria
Success - 200 Ok - With an empty array
Get specific
---------------------------------------------------------------------
Success - 200 Ok - The entity matching the identifier specified is returned as content
Failure - 404 NotFound - No content
Action
---------------------------------------------------------------------
Success - 200 Ok - Return content where appropriate
Success - 204 NoContent
Failure - 400 - Return details about the failure
Async fire and forget operation - 202 Accepted - Optionally return url for polling status
Generic results
---------------------------------------------------------------------
Authorization error 401 Unauthorized
Authentication error 403 Forbidden
For methods not supported 405
Generic server error 500
Comments
The HTTP/1.1 spec (section 9.6) discusses the appropriate response/error codes. However it doesn't address the response content.
What would you expect ? A simple HTTP response code (200 etc.) seems straightforward and unambiguous to me.
5 Comments
Http response code of 201 for "Created" along with a "Location" header to point to where the client can find the newly created resource.
7 Comments
I used RESTful API in my services, and here is my opinion:
First we must get to a common view: PUT is used to update an resource not create or get.
I defined resources with: Stateless resource and Stateful resource:
Stateless resources For these resources, just return the HttpCode with empty body, it's enough.
Stateful resources For example: the resource's version. For this kind of resources, you must provide the version when you want to change it, so return the full resource or return the version to the client, so the client need't to send a get request after the update action.
But, for a service or system, keep it simple, clearly, easy to use and maintain is the most important thing.
1 Comment
RFC7231 does not specify the response body of a PUT method. Do whatever works for you. For example,
- Empty (use status No Content to avoid some problems).
- The updated resource representation.
- Anything.
HTTP does not define exactly how a PUT method affects the state of an origin server beyond what can be expressed by the intent of the user agent request and the semantics of the origin server response.
If the target resource does not have a current representation and the PUT successfully creates one, then the origin server MUST inform the user agent by sending a 201 (Created) response.
Responses to the PUT method are not cacheable.
Comments
seems ok... though I'd think a rudimentary indication of success/failure/time posted/# bytes received/etc. would be preferable.
edit: I was thinking along the lines of data integrity and/or record-keeping; metadata such as an MD5 hash or timestamp for time received may be helpful for large datafiles.
2 Comments
Ideally it would return a success/fail response.
1 Comment
There's a difference between the header and body of a HTTP response. PUT should never return a body, but must return a response code in the header. Just choose 200 if it was successful, and 4xx if not. There is no such thing as a null return code. Why do you want to do this?
