How do I create an HTTP PUT request that modifies the resource in many ways
https://softwareengineering.stackexchange.com/questions/394649
-
27-02-2021 - |
Pregunta
I have a NodeJs backend that interacts with MySQL database. Let us assume that I have a schema similar to this:
Book
id
name
Author
id
book_id
name
So, I have two tables named Book and Author having 1-M relationship between them such that 1 book can have multiple authors.
Now, I have designed a GET
request for a particular book which takes a book_id as a parameter and return its details
endpoint: http:api.some_domain.com/book/34
response:
{
book_id: 34
name: "Stack Exchange Essentials"
author: [
{
id: 1,
book_id: 34,
name: "John"
},
{
id: 2,
book_id: 34,
name: "Henry"
}
]
}
Now, my goal is to design a PUT
request for a book resource that will be responsible for:
- Updating a book name
- Updating the authors' name
- Removing the existing author
- Addition of a new author
How do I handle the above problem?
Should I create a separate
PUT
andPATCH
requests to handle full and partial update of the resource?Should I handle author deletion in a separate
DELETE
requestIf I handle everything in 1 single request, should I expect client to send me the full updated resource?
Please note that I have used Book and Author here for simplicity, but in reality I have different resources. Also note that an Author cannot be directly fetched without a book.
Solución
A PUT request should completely replace the resource, so this is essentially a non-issue. If you want to update multiple aspects while keeping some information, PATCH is the right verb to use, and you should have a look at JSON Patch as the message format, it is well-designed and has good implementations.
Regarding the book/author relationship (or whatever it is in reality): books and authors are different resources, and books should reference their authors using URLs. Book IDs should not be part of author resources, though. However, as always, it's difficult to give advice for your actual problem if you present a toy problem instead that may or may not map well to the real problem.
If it is actually a composite/part relationship you can either keep the parts "anonymously" within their composite resource, or you can choose to give them their own resource URL as a sub-url (e.g. /api/composites/:c-id/parts/:p-id), which would allow you to add or delete parts to/from an existing composite without implementing a PATCH operation.