8.1 KiB
type |
---|
practical |
Updating information
Can we have optional fields in the update PUT
and POST
request?
The existence of the PATCH
request
The
PATCH
HTTP method applies partial modifications to a resource.PATCH
is somewhat analogous to the "update" concept found in CRUD (in general, HTTP is different than CRUD, and the two should not be confused).1
Hence, this definition also answers the question as to why we should be careful with the usage of PATCH
if we consider it.
Usage of 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. 2
This implies that complete resource representation is required (all the fields), as Jackson(Spring) will reset the missing ones to their default values (e.g. int = 0, boolean = false, String = null, etc.)
Complete request example
Request:
{
"isbn": "978-3-16-148410-0",
"name": "Among us story",
"author": "Yo mama",
"genre": "Horror",
"publisher": "Team 22",
"publishDate": "2023-09-01",
"pages": 320
}
Response:
<<< 200 OK
{
"isbn": "978-3-16-148410-0",
"name": "Among us story",
"author": "Yo mama",
"genre": "Horror",
"publisher": "Team 22",
"publishDate": "2023-09-01",
"pages": 320
}
Incomplete request example
(this is assuming the above request happened already) Request:
{
"isbn": "978-3-16-148410-0",
"name": "Among us story",
"publisher": "Team 22",
"pages": 320
}
Response:
<<< 200 OK
{
"isbn": "978-3-16-148410-0",
"name": "Among us story",
"author": null,
"genre": null,
"publisher": "Team 22",
"publishDate": null,
"pages": 320
}
Usage of POST
Contrary to PUT
:
The
POST
method is used to request that the target resource process the enclosed representation according to the resource's own specific semantics. The meaning of aPOST
request is determined by the server and is usually dependent on the resource identified by the Request-URI.3
Therefore we can send requests which contain data that are non-complete resource representations. We do have to explain this to the other team tho...
i.e. Request:
{
"isbn": "978-3-16-148410-0"
}
Response:
<<< 201 Created
{
"isbn": "978-3-16-148410-0",
"name": null,
"author": null,
"genre": null,
"publisher": null,
"publishDate": null,
"pages": 0
}
General "style" remarks
(based on the API conventions + CRUD principle)
The base URL should be neat, elegant, and simple so that developers using your product can easily use them in their web applications. A long and difficult-to-read base URL is not just bad to look at, but can also be prone to mistakes when trying to recode it. Nouns should always be trusted.4
Hence, using a verb in POST /api/v1/book/create
and PUT /api/v1/book/update
is not ideal.
Table4 of common conventions for the usage of HTTP requests:
Resource | POST |
GET |
PUT |
DELETE |
---|---|---|---|---|
/customers | Create a new customer | Retrieve all customers | Bulk update of customers | Remove all customers |
/customers/1 | Error | Retrieve the details for customer 1 | Update the details of customer 1 if it exists | Remove customer 1 |
/customers/1/orders | Create a new order for customer 1 | Retrieve all orders for customer 1 | Bulk update of orders for customer 1 | Remove all orders for customer 1 |
Hence, in our case:
Resource | POST |
GET |
PUT |
DELETE |
---|---|---|---|---|
/books | Create a new book | Retrieve all books (+ optional parameters for filtering) | 405 | Remove all books |
/books/{isbn} | 405 | Retrieve the details for book with isbn |
Update the details of book with isbn if exists |
Remove book with isbn |
Conclusion / TL;DR
Given the information provided above, I propose we change the current specification as follows:
Method | Old URL/Description | New URL/Description | Reasoning |
---|---|---|---|
POST |
/api/v1/book/create - Create book - pass JSON body (isbn is required) |
/api/v1/books - Create a book - pass JSON body (isbn is required) |
Use resource-based naming convention (books as a collection). HTTP POST implies creation; no need for /create . |
PUT |
/api/v1/book/update - Update book - pass JSON body (isbn is required) |
/api/v1/books/{isbn} - Update a specific book - pass JSON body |
Use path parameter ({isbn} ) to specify which book to update. HTTP PUT implies updating a specific resource. |
GET |
/api/v1/book?genre={genre}&author={author}&data="csv" - Get book(s) by property in csv/json format |
/api/v1/books?genre={genre}&author={author} - Get books by property. Use Accept header for csv/json format |
Use plural books for collections. Use HTTP Accept header for content negotiation (CSV/JSON), keeping URLs clean. |
DELETE |
/api/v1/book?genre={genre}&author={author} - Delete book(s) by property |
/api/v1/books - Delete books - pass filter criteria in body or delete one by /api/v1/books/{isbn} |
DELETE requests with body for filtering criteria, or use path param for deleting a single resource for better clarity. |
POST |
/api/v1/book/import?data="csv" - Import books from csv/json file (isbn is required for each) |
/api/v1/books/import - Import books from CSV/JSON file - pass file in body; use Content-Type header |
Use resource-based naming (books/import ). The Content-Type header indicates file type (CSV/JSON); keep query params clean. |