When designing a REST API for update request. Usually PUT is used. Question: should the resource URL include the id usually?
For instance, there is a book resource: http://localhost:8080/library/book
When updating a given book with Id, say 123
, we could send a PUT request with JSON as the HTTP request body as the update resource. The URL can include the id of the book, e.g. http://localhost:8080/library/book/123
But is this OK? or should we always avoid giving the id in the URL for update request?
3 Answers 3
When designing a REST API for update request. Usually PUT is used. Question: should the resource URL include the id usually?
The target URI of the PUT request should match the target URI of the GET request used to retrieve a representation of the same resource.
GET /a86e4776-699e-428a-b1a8-5c2828910d86
200 OK
Content-Type: text/plain
Helo World
PUT /a86e4776-699e-428a-b1a8-5c2828910d86
Content-Type: text/plain
Hello World
Therefore, including an "id" in the URI for a PUT request follows precisely the same rules as including an "id" in the URI for a GET request.
The same is true, of course, for POST, PATCH, DELETE, HEAD, etc. The resource identifier identifies the resource.
Now, your local spelling conventions may say that resource identifiers can include identifiers, or not, or only obfuscated identifiers, or whatever. Those kinds of design decisions are local to you, and will be motivated by the kinds of things that are most important to you (ex: we want to make things easy for the operators who need to read our access logs).
Reviewing Webber, 2011 may help clarify
HTTP is an application protocol, whose application domain is the transfer of documents over a network.
-
1sounds like you disagree with amon about POST?Ewan– Ewan02/13/2022 17:26:12Commented Feb 13, 2022 at 17:26
-
1Really? what part?VoiceOfUnreason– VoiceOfUnreason02/13/2022 19:00:33Commented Feb 13, 2022 at 19:00
-
1"The same is true, of course, for POST, PATCH, DELETE, HEAD, etc. The resource identifier identifies the resource."Ewan– Ewan02/13/2022 21:17:01Commented Feb 13, 2022 at 21:17
-
2I think amon and I are in complete agreement on that point. We might disagree about which resource in your resource model should handle a POST request (there are trade offs) but I'm sure we understand target URI the same way. If you think that's still unclear, it might make sense to pose it as a question....VoiceOfUnreason– VoiceOfUnreason02/14/2022 03:04:17Commented Feb 14, 2022 at 3:04
An URI identifies a resource. A PUT request is supposed to create or replace the representation of that resource. So, if you want to replace the state of book 123
, you should PUT /book/123
. Think of PUT
as uploading an entire file, but you have to give the target "filename". There is a strong expectation that if you do a PUT /url
and later GET /url
, you'd get back an equivalent representation to what you've uploaded. This indicates that PUT /book
would be incorrect since a later GET /book
probably wouldn't return the data you've just uploaded about book 123.
If you want to perform a partial update of a book's state, use a PATCH
request. This too would generally require the resource's ID in the URI.
If you want the endpoint to perform some other action, consider a POST
request. For example POST /book
might use the body of the request to figure out which resources should be affected. If you're not sure which HTTP request method to use but if you want the server to do something (possibly with side effects), then POST
is a good default. POST
is most commonly used for form submissions, but it's also often used for creating new resources if the server should assign the ID.
Recommended further reading: HTTP request methods on MDN and Request Methods in RFC 7231.
-
In general I agree with all of these points, although in practice I usually just use PUT for all updates (full or partial). Callers don't really care about the distinction between PUT and PATCH - they just want to update the data.Greg Brown– Greg Brown07/07/2023 12:25:18Commented Jul 7, 2023 at 12:25
No.
If you are updating resource you will be sending the whole resource in the body, and this will include the Id.
So sending it twice is unnecessary at best and introduces an error (if there is a mismatch) at worst.
Amon and Voice of Unreason, object that the URI = the resource that the put must replace. But I would argue that this is an overly strict interpretation, which is only applicable where the id is the filename.
After all, in such a case you would have to replace book 1 with book 2 if you sent id 2 in the content. Also the equivalent POST documentation insists the only difference is the idempotency of the request, but is happy to have a single url for different documents.
Say you programmed both solutions. The strict interpretation would require a check that both ids matched, whereas my practical interpretation would not. My solution would use less electricity and be faster, cheaper to run and throw less errors.
-
2For a POST request, I'd agree. But for a PUT request, your recommendations violate the semantics of this request type.amon– amon02/13/2022 15:50:19Commented Feb 13, 2022 at 15:50
-
-
I think this is given by section 4.3.4 of RFC 7231: "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." The "target resource" is identified by the request URI (compare section 2), not by the payload contents.amon– amon02/13/2022 18:40:22Commented Feb 13, 2022 at 18:40
-
seems like there is a handy get out clause "A PUT request applied to the target resource can have side effects on other resources."Ewan– Ewan02/13/2022 21:16:05Commented Feb 13, 2022 at 21:16
-
1Ewan, I agree with you from a practical point of view: adding ID to the URI has one only advantage: being able to change the ID of the resource. Considering most systems don't want this, I think it is sheer unnecessary redundancy.César Rodriguez– César Rodriguez08/24/2025 15:58:30Commented Aug 24 at 15:58