I use Laravel as a REST API service for uploading and storing books. The book service follows the standard REST convention:
GET: /api/books and /api/books/<book_id> for retrieving book(s)
PUT: /api/books/<book_id> for updating a book
POST: /api/books for adding a new book
DELETE: /api/books/<book_id> for deleting a book
So far so good.
Now I need another endpoint which should be used for creating a Zip file out of a book and some images. So the book is already on the server (in a database). The images need to be uploaded temporarily by the client and are NOT saved on the server. Then the images and the books are compressed and the resulting file is returned back to the client.
So I need an endpoint like /api/books/{book_id}/compress. When calling this endpoint, the client attaches the images in the request body.
How do I express that in a RESTful way?
Should that be a GET or POST request? This endpoint does not store anything on the server, so it should be a GET request from my point of view. But if it is GET, can I add images to the request body? Because that's actually supposed to be handled by POST requests.
CodePudding user response:
Funny you ask. I have had the same question once before and I remember someone telling me that a GET request originally does not have a request body. However I think (so I am not sure) it was still possible. Unfortunately I am unable to find that example.
According to the w3 documentation the POST request can be used for the following:
- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
- Providing a block of data, such as the result of submitting a form, to a data-handling process;
- Extending a database through an append operation.
I think in your case the "Providing a block of data, such as the result of submitting a form, to a data-handling process;" applies here.
Personally I am very strict in following a certain pattern in route definition and their purpose: /{resource}/{identifier?}/{relatedResource?|action?}.
In this case I would agree with /api/books/{book_id}/compress since it comlies with the listed usecases of POST.
CodePudding user response:
But if it is GET, can I add images to the request body?
It's not a great idea...?
Here's what the current standard has to say about GET
Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics
A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported.
An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.
"No generally defined semantics" is kind of like "undefined behavior" - if something goes sideways, resulting in loss of property, the liability is going to be on you.
On the other hand: it is okay to use POST.
POST serves many useful purposes in HTTP, including the general purpose of "this action isn’t worth standardizing." -- Fielding, 2009
Today, we don't have a standardized HTTP method that combines safe semantics and a request payload.
But: there is a work in progress that is intended to support queries in the body of a request, and it may turn out that the same semantics can be used for transformations.
