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.

    链接地址: http://www.djcxy.com/p/71450.html

    上一篇: 对于Restful API,GET方法可以使用json数据吗?

    下一篇: 可以请求更改URL?