Can PUT request change the URL?
My application with a HTTP API provides some resources that are identified by name. So, the URLs are constructed as the following:
/path/to/resources/<name>
For example:
/path/to/resources/my_resource
The resources can be updated with PUT operations. It is also allowed to rename a resource with such an update.
PUT /path/to/resources/my_resource
{"name": "new_name", <other properties>}
Response:
HTTP/1.1 204 No content
As a result, the updated resource is now accessible under a new URL:
GET /path/to/resources/new_name
Response:
HTTP/1.1 200 OK
{"name": "new_name", <other properties>}
The old URL is no longer valid:
GET /path/to/resources/my_resource
Response:
HTTP/1.1 404 Not found
Is such behavior correct? Should the PUT operation return the Location
header with a new URL? Is it OK to return the Location
header with the 204 No content
status?
After writing this question I found another, quite similar: REST API Design : Is it ok to change the resource identifier during a PUT call? The accepted answer was that it is allowed, but not recommended. Still don't know what about the Location
header, though.
By changing a resource identifier, I understand you are deleting a resource and creating a new one. So, the approach you described in the question is basically a delete operation using the wrong HTTP verb.
According to the RFC 7231, the current reference for HTTP/1.1, PUT
requests are used to create or replace a resource:
4.3.4. PUT
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.
[...]
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. If the target resource does have a current representation and that representation is successfully modified in accordance with the state of the enclosed representation, then the origin server MUST send either a 200
(OK) or a 204
(No Content) response to indicate successful completion of the request.
[...]
I would do the following when the resource identifier needs to be changed:
Perform a DELETE
in the existing resource. The response would be a 204
indicating the request was fulfilled.
Perform a POST
or PUT
to create the resource using the new identifier. The response would be a 201
indicating the resource was created. The response would contain a Location
header indicating where the resource is located.
To replace the state of the target resource (keeping the resource identifier), perform a PUT
and return a 204
to indicate the operation succeeded.
I don't know about your requirements, but I wouldn't allow the user to change or create the identifier of a resource. I would assume the resource identifier is immutable and should be generated by the application (UUID, of example) or an identifier generated by the database.
I agree with Cássio Mazzochi Molin's answer. However the question is theoretical one, whether renaming the resource really changes the 'identity' of a resource.
For example if a person's name changes, that does not change who the person is. I still would like the URI
I previously got for the "same" person to work, even after the name change.
So I guess my point is not to include non-identity related information into the URI
. Include an Id number
or similar content-unrelated information.
Don't do a DELETE
and PUT
to another URI
(don't relocate the resource) if the identity of the object did not change.
上一篇: 对于Restful API,GET方法可以使用json数据吗?
下一篇: 可以请求更改URL?