ChatGPT解决这个技术问题 Extra ChatGPT

Should a RESTful 'PUT' operation return something....

I was wondering what people's opinions are of a RESTful PUT operation that returns nothing (null) in the response body.


F
Fletch

The HTTP specification (RFC 2616) has a number of recommendations that are applicable. Here is my interpretation:

HTTP status code 200 OK for a successful PUT of an update to an existing resource. No response body needed. (Per Section 9.6, 204 No Content is even more appropriate.)

HTTP status code 201 Created for 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 Conflict for 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 Request for 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)


@stian Interesting! That seems pretty presumptuous on the part of Mozilla, since I can find nothing in RFC 2616 (notably sections 10.2 Successful 2xx and 10.2.1 200 OK) that specifically rule out the use of 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.
@stian: That sentence was removed on Feb 3 2013. Probably because someone read about it here. ;) developer.mozilla.org/en-US/docs/HTTP/…
The semantics of the PUT method is to ignore whatever current state the resource is in, therefore to return a 409 conflict for a PUT that is unsuccessful due to a 3rd party modification only makes sense if the request is conditional.
@systemPAUSE Nice answer. One small point: if you are not going to be returning a response body to a successful operation, I would suggest using a 204 exclusively. Some clients (jQuery Ajax, for example) will choke if they are expecting a non-zero length response but don't get it. You can see an example of this in this question.
Possibly RFC2616 has been updated since this was answered. No where in 9.6 does it mention 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.
L
LiorH

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


@Raedwald sure it is. REST doesn't require that the entire resource be updated on a PUT, although it's generally recommended. Some fields might not make sense to update -- created date or last modified date, for example, should probably not be included in the PUT body, but would likely be changed as a result of the PUT. That having been said, I do not agree with LiorH that a PUT should result in a return of the resource; I would require a GET after the PUT to obtain the updated resource.
@Randolpho REST doesn't require that the entire resource be updated on a PUT shouldn't this be the case of a PATCH?
@MarcoCiambrone Yes, I agree and I recant my previous comment. I've changed my tune on REST and PUT -- PUT should always be idempotent and should never be used for a partial update. POST is the only alternative unless PATCH is supported, in which case PATCH may be a good alternative. PATCH is a new verb, however, and may not be supported by some server-side frameworks.
The answer was written well before rfc7231, but section 4.3.4 makes it clear "The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload"
What if the updated object is large? Seems wasteful to return a lot of data that isn't likely to be used.
s
shaunc

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.


J
John Henckel

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.


B
Brian Agnew

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.


Yes, but what if you want to check whether the inserted data into db after a PUT or POST really represents the true data you want. It would be better if the HTTP can send back the body of the response.
@tnkh what you suggest is downright a horrible idea. Make a separate GET call after a successful update to achieve what you want. In order to ensure performance introduce a caching layer if you are facing issues in this department. We can't solve these issues by messing around with 'everything goes' kind of logic. Don't mess around with 'solid' and basic programming principles which should be common sense in the year 2020. It's a disgrace!
@XDS I acknowledge your first part of the comment. But cant stop to roll my eyes after that. Hilarious comment
Thanks on elaborating on why you find it hilarious though.
P
Pravind Kumar

https://i.stack.imgur.com/JwL5C.png


d
dc360

Http response code of 201 for "Created" along with a "Location" header to point to where the client can find the newly created resource.


PUT objects aren't (or shouldn't be) newly created resources
@kdazzle PUT can certainly be a newly created resource, and often would be. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Just to explain my comment a bit better. PUT means, put this item at this specific location, replacing what's currently there (if applicable).
Right, "replacing what's currently there" is the key phrase. It should already exist and it is being replaced. PUT should not be for creating new resources.
@KevinM As in the latest RFC doc rfc7231, it says that resources can be created: "The PUT method requests that the state of the target resource be created or replaced [...]" and the reason you're thinking PUT cannot create new resource is because you don't necessarily know the location of the new resource. But if you know its location/identifier, it can be created if it's not yet there.
B
Bruce

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.


"PUT is used to update an resource not create or get." - that's not true nor common. By spec, PUT can create the resource. Clear = following the commonly known spec.
A
AnthonyWJones

Just as an empty Request body is in keeping with the original purpose of a GET request and empty response body is in keeping with the original purpose of a PUT request.


J
Jason S

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.


How about 200 OK in the status response header? Do think thats enought to say, "Worked fine thanks?"
the response header would contain the status code, and yes we are talking about HTTP at this point :)
c
cgp

Ideally it would return a success/fail response.


Not in the response body, though. The HTTP status code is the place for that. Maybe if there's an error some extended error information could be returned in the response bidy
A
AlexanderJohannesen

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?


There's no such reference on RFC about the statement "PUT should never return a body". Furthermore, if you choose to return 200, this means you probably do return a body (unless you choose for 204)