We are planning to use GET for all retrievals and DELETE for all delete operations.
HTTP PUT , POST and PATCH is confusing. After a lot of reading, this is my understanding. Please correct if I am wrong.
POST - Not Idempotent ; so can be used for creating new resources/subordinate resource. Each time it creates a new one the ID gets changed and so it is best suited.
PUT - Idempotent; cannot be used for create since the second time the same request comes, it creates a new resource again with different ID.
Can be used for update but all attributes should be passed each time it is updated. To achieve this, a GET should be done prior to update operation. Overhead.
Why not use POST for updates too?
PATCH -Not sure if it is suitable for JAX-RS 1.1.
Thanks in advance.
I think your question is this:
Why not use POST for updates too?
The benefit of having POST and PUT make different types of changes to the resource you're allowing an extra vector of the request to modify the action without having to add more URLs. That way, URLs can stay short, clean, and reflective of what it is the represent.
However, to clear things up PATCH is often used for partial updates. So, like PUT it is idempotent, but will only modify the parts of the resource which you send in the request body whereas PUT is expected to modify the whole thing. This is often overlooked in REST. You can read more on the Rest Cookbook website.
Apart from that, from what I can tell your understanding is very good. Enjoy RESTing!
Related
I want to implement a DELETE REST API. But I need the option to provide a list of IDs to be deleted. This list could be arbitrarily long and may not fit within a URL.
I know POST supports this, but support for this and DELETE seems debatable. I wonder how others are handling this case.
How would an API be designed to handle this case?
This is unfortunately one of the biggest limitations in REST, but there are ways around it.
In this case I would abstract out a new entity, DeletionRequest, and have that get posted or put with the appropriate IDs. Since it is a new entity it would have its own rest endpoints.
A nice side effect of this is that the endpoints and entity can be expanded out to support async requests. If you want to delete a ton of data you don't want to rely on it happening in a single request, as things like timeouts can get in the way. With a DeletionRequest the user can get an ID for the deletion request on the first push, and then check the status with a GET request. Behind the scenes you can use an async system (celery, sidekiq, etc) to actually delete things and update the status of the DeletionRequest.
You don't have to take it that far to start, of course, but this would allow you to expand the application in that direction without having to change your API.
The URI is the resource identifier, so in my opinion the DELETE should not contain a body even if you can do it with your client and server. Either you send your data in the URI or you send it prior the DELETE.
I see 3 options here, but maybe there are others:
Do what Robert says and POST a transaction resource instead like DeletionRequest.
Group the resources you want to delete and DELETE the entire group.
Do a massive hack and PATCH the collection of resources you want to delete from.
I am developing my own REST API and was looking for other well-established APIs to see what they do when they have a need to expose some sort of action that can be made on a resource. One that came up was the ability to star and unstar a repository/gist on GitHub. According to their docs, you can star with PUT /gists/{gist_id}/star, and unstar with DELETE /gists/{gist_id}/star.
This is what the docs say about the HTTP verbs:
PUT Used for replacing resources or collections. For PUT requests with no body attribute, be sure to set the Content-Length header to zero.
DELETE Used for deleting resources.
Delete makes sense to me, but why would PUT be used? Since you can GET /gists/{gist_id}/star it seems "star" is some sort of functional resource. So I guess I'm just wondering why PUT instead of POST?
So I guess I'm just wondering why PUT instead of POST?
PUT, in HTTP, has somewhat tighter constraints on its semantics than POST does -- for instance, the semantics of PUT are idempotent, which is a convenient thing to know when you are sending requests over an unreliable network; PUT tells you that there won't be a problem if the server receives more than one copy of the request message.
(This is a lot like asking about why GET instead of POST, except that the differences are smaller)
Which is why when you have a simple remote authoring use case, like uploading a document to a document store, that PUT is the superior choice -- because it allows general purpose clients (like browsers) to do useful things without needing extra out of band information.
https://docs.github.com/en/rest/overview/resources-in-the-rest-api#http-verbs does NOT define the semantics of the HTTP methods. The standardized definitions of GET, PUT, POST and so on are in RFC 7231.
If you review the RFC, you'll discover that the semantics of HTTP PUT also cover "create":
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.
"Make your copy of this document look like my copy" is a perfectly reasonable way to communicate information to the server, and the meaning of that message doesn't really depend at all on whether or not the server already knows about the document when the request is processed.
I am developing my own REST API
Do make sure you review Jim Webber's 2011 talk, which I think goes a long way toward clarifying how web based API are "supposed" to work.
One reason I could see is that the star “exists”, and these routes are just toggling some sort of “active” property on the star. So you wouldn’t use POST because you’re not creating the star, just toggling its active property.
Edit: this is also just a guess based on how I’d implement something like this, as their docs are kind of sparse.
I'm building a REST API and I'm trying to keep it as RESTful as possible, but some things are still not quite clear for me. I saw a lot of topic about similar question but all too centered about the "simple" problem of updating data, my issue is more about the business logic around that.
My main issue is with business logic triggered by partial update of a model. I see a lot of different opinion online about PATCH methods, creating new sub-ressources or adding action, but it often seems counter productive with the REST approach of keeping URI simple and structured.
I have some record that need to be proceeded ( refused, validated, partially validated ..etc ), each change trigger additional actions.
If it's refused, an email with the reason should be sent
if it's partially validated, the link to fulfill the missing data is sent
if it's validated some other ressources must be created.
There is a few other change that can be made to the status but this is enough for the example.
What would be a RESTful way to do that ?
My first idea would be to create actions :
POST /record/:id/refuse
POST /record/:id/validate ..etc
It seems RESTful to me but too complicated, and moreover, this approach means having multiple route performing essentially the same thing : Update one field in the record object
I also see the possibility of a PATCH method like :
PATCH /record/:id in which I check if the field to update is status, and the new value to know which action to perform.
But I feel it can start to be too complex when I will have the need to perform similar action for other property of the record.
My last option, and I think maybe the best but I'm not sure if it's RESTful, would be to use a sub-ressource status and to use PUT to update it :
PUT /record/:id/status, with a switch on the new value.
No matter what the previous value was, switching to accepted will always trigger the creation, switching to refused will always trigger the email ...etc
Are those way of achieving that RESTful and which one make more sense ? Is there other alternative I didn't think about ?
Thanks
What would be a RESTful way to do that ?
In HTTP, your "uniform interface" is that of a document store. Your Rest API is a facade, that takes messages with remote authoring semantics (PUT/POST/PATCH), and your implementation produces useful work as a side effect of its handling of those messages.
See Jim Webber 2011.
I have some record that need to be proceeded ( refused, validated, partially validated ..etc ), each change trigger additional actions.
So think about how we might do this on the web. We GET some resource, and what is returned is an html representation of the information of the record and a bunch of forms that describe actions we can do. So there's a refused form, and a validated form, and so on. The user chooses the correct form to use in the browser, fills in any supplementary information, and submits the form. The browser, using the HTML form processing rules, converts the form information into an HTTP request.
For unsafe operations, the form is configured to use POST, and the browsers therefore know that the form data should be part of the message-body of the request.
The target-uri of the request is just whatever was used as the form action -- which is to say, the representation of the form includes in it the information that describes where the form should be submitted.
As far as the browser and the user are concerned, the target-uri can be anything. So you could have separate resources to handle validate messages and refused messages and so on.
Caching is an important idea, both in REST and in HTTP; HTTP has specific rules baked into it for cache invalidation. Therefore, it is often the case that you will want to use a target-uri that identifies the document you want the client to reload if the command is successful.
So it might go something like this: we GET /record/123, and that gives us a bunch of information, and also some forms describing how we can change the record. So fill one out, submit it successfully, and now we expect the forms to be gone - or a new set of forms to be available. Therefore, it's the record document itself that we would expect to be reloading, and the target-uri of the forms should be /record/123.
(So the API implementation would be responsible for looking at the HTTP request, and figuring out the meaning of the message. They might all go to a single /record/:id POST handler, and that code looks through the message-body to figure out which internal function should do the work).
PUT/PATCH are the same sort of idea, except that instead of submitting forms, we send edited representations of the resource itself. We GET /record/123, change the status (for example, to Rejected), and then send a copy of our new representation of the record to the server for processing. It would therefore be the responsibility of the server to examine the differences between its representation of the resource and the new provided copy, and calculate from them any necessary side effects.
My last option, and I think maybe the best but I'm not sure if it's RESTful, would be to use a sub-resource status and to use PUT to update it
It's fine -- think of any web page you have ever seen where the source has a link to an image, or a link to java script. The result is two resources instead of one, with separate cache entries for each -- which is great, when you want fine grained control over the caching of the resources.
But there's a trade - you also need to fetch more resources. (Server-push mitigates some of this problem).
Making things easier on the server may make things harder on the client - you're really trying to find the design with the best balance.
I understand (From the accepted answer What is the difference between HTTP and REST?)
that REST is just a set of rules about how to use HTTP
Accepted answer says:
No, REST is the way HTTP should be used.
Today we only use a tiny bit of the HTTP protocol's methods – namely
GET and POST. The REST way to do it is to use all of the protocol's
methods.
For example, REST dictates the usage of DELETE to erase a document (be
it a file, state, etc.) behind a URI, whereas, with HTTP, you would
misuse a GET or POST query like ...product/?delete_id=22
My question is what is the disadvantage/drawback(technical or design) If I continue to use the POST method instead of DELETE/PUT for deleting/updating the resource in Rest?
My question is what is the disadvantage/drawback(technical or design)
If I continue to use POST method instead of DELETE/PUT for
deleting/updating the resource in Rest ?
The POST request is not Idempotent but the DELETE request is Idempotent.
An idempotent HTTP method is a HTTP method that can be called many times without different outcomes
Idempotency is important in building a fault-tolerant API.
Let's suppose a client wants to update a resource through POST. Since POST is not an idempotent method, calling it multiple times can result in wrong updates. What would happen if you sent out the POST request to the server, but you get a timeout. Did the resource actually get updated? Did the timeout happen when sending the request to the server, or when responding to the client? Can we safely retry again, or do we need to figure out first what happened with the resource? By using idempotent methods, we do not have to answer this question, but we can safely resend the request until we actually get a response back from the server.
So, if you use POST for deleting, there will be consequences.
From a purely technical viewpoint, I am not aware of any real drawbacks. Others mentioned idempotency, but that does not come just by using DELETE, you still have to implement it anyway.
Which leaves us with design considerations:
Your clients (or rather the programmers programming against your API) might reasonably expect the DELETE method to delete things and the POST method to add things. If you don't follow that convention, you confuse them.
If you use POST for both deleting and adding things, you have to invent another way of telling what actually to do. Surely this isn't very hard, but it makes your API more complicated for no good reason.
For both these reasons, you will need more and better documentation, since you're not following RESTful principles, which are already documented.
When we use POST instead of Delete in our rest API then we are snatching power of Idempotency from client.That means,By using POST we are saying to our API user that this API can produce differnent result upon hitting multiple time.
In case of Timeout, API user have to enquiry for the resource
which he had made a request to delete.Then if found,he has to made a
call to POST API to delete it.
Where if same request is made using Delete method.Then we are assuring
our API user that multiple calls to same method will return same
result. Hence he can raise any number of request untill he gets
successful deletion instead of Timeout without enquriy.
Note : Maintaining Idempotency is the duty of API maker.Just putting Delete method do not give Idempotency.
In REST generally we know that POST use to Add something, PUT use to Edit something in existing data and DELETE is use for Delete something and POST request is not Idempotent but the DELETE request is Idempotent.
Although above are definition but in my point of view We are using these methods because for better understanding that particular method is use for what purpose and by using these methods the bridge between UI developer and Backend developer will not be minimized.
if you want to use POST method instead of DELETE/PUT then there will
not any impact but this is not a good coding standard.
What is the REST-ful way of deleting multiple items?
My use case is that I have a Backbone Collection wherein I need to be able to delete multiple items at once. The options seem to be:
Send a DELETE request for every single record (which seems like a bad idea if there are potentially dozens of items);
Send a DELETE where the ID's to delete are strung together in the URL (i.e., "/records/1;2;3");
In a non-REST way, send a custom JSON object containing the ID's marked for deletion.
All options are less than ideal.
This seems like a gray area of the REST convention.
Is a viable RESTful choice, but obviously has the limitations you have described.
Don't do this. It would be construed by intermediaries as meaning “DELETE the (single) resource at /records/1;2;3” — So a 2xx response to this may cause them to purge their cache of /records/1;2;3; not purge /records/1, /records/2 or /records/3; proxy a 410 response for /records/1;2;3, or other things that don't make sense from your point of view.
This choice is best, and can be done RESTfully. If you are creating an API and you want to allow mass changes to resources, you can use REST to do it, but exactly how is not immediately obvious to many. One method is to create a ‘change request’ resource (e.g. by POSTing a body such as records=[1,2,3] to /delete-requests) and poll the created resource (specified by the Location header of the response) to find out if your request has been accepted, rejected, is in progress or has completed. This is useful for long-running operations. Another way is to send a PATCH request to the list resource, /records, the body of which contains a list of resources and actions to perform on those resources (in whatever format you want to support). This is useful for quick operations where the response code for the request can indicate the outcome of the operation.
Everything can be achieved whilst keeping within the constraints of REST, and usually the answer is to make the "problem" into a resource, and give it a URL.
So, batch operations, such as delete here, or POSTing multiple items to a list, or making the same edit to a swathe of resources, can all be handled by creating a "batch operations" list and POSTing your new operation to it.
Don't forget, REST isn't the only way to solve any problem. “REST” is just an architectural style and you don't have to adhere to it (but you lose certain benefits of the internet if you don't). I suggest you look down this list of HTTP API architectures and pick the one that suits you. Just make yourself aware of what you lose out on if you choose another architecture, and make an informed decision based on your use case.
There are some bad answers to this question on Patterns for handling batch operations in REST web services? which have far too many upvotes, but ought to be read too.
If GET /records?filteringCriteria returns array of all records matching the criteria, then DELETE /records?filteringCriteria could delete all such records.
In this case the answer to your question would be DELETE /records?id=1&id=2&id=3.
I think Mozilla Storage Service SyncStorage API v1.5 is a good way to delete multiple records using REST.
Deletes an entire collection.
DELETE https://<endpoint-url>/storage/<collection>
Deletes multiple BSOs from a collection with a single request.
DELETE https://<endpoint-url>/storage/<collection>?ids=<ids>
ids: deletes BSOs from the collection whose ids that are in the provided comma-separated list. A maximum of 100 ids may be provided.
Deletes the BSO at the given location.
DELETE https://<endpoint-url>/storage/<collection>/<id>
http://moz-services-docs.readthedocs.io/en/latest/storage/apis-1.5.html#api-instructions
This seems like a gray area of the REST convention.
Yes, so far I have only come accross one REST API design guide that mentions batch operations (such as a batch delete): the google api design guide.
This guide mentions the creation of "custom" methods that can be associated via a resource by using a colon, e.g. https://service.name/v1/some/resource/name:customVerb, it also explicitly mentions batch operations as use case:
A custom method can be associated with a resource, a collection, or a service. It may take an arbitrary request and return an arbitrary response, and also supports streaming request and response. [...] Custom methods should use HTTP POST verb since it has the most flexible semantics [...] For performance critical methods, it may be useful to provide custom batch methods to reduce per-request overhead.
So you could do the following according to google's api guide:
POST /api/path/to/your/collection:batchDelete
...to delete a bunch of items of your collection resource.
I've allowed for a wholesale replacement of a collection, e.g. PUT ~/people/123/shoes where the body is the entire collection representation.
This works for small child collections of items where the client wants to review a the items and prune-out some and add some others in and then update the server. They could PUT an empty collection to delete all.
This would mean GET ~/people/123/shoes/9 would still remain in cache even though a PUT deleted it, but that's just a caching issue and would be a problem if some other person deleted the shoe.
My data/systems APIs always use ETags as opposed to expiry times so the server is hit on each request, and I require correct version/concurrency headers to mutate the data. For APIs that are read-only and view/report aligned, I do use expiry times to reduce hits on origin, e.g. a leaderboard can be good for 10 mins.
For much larger collections, like ~/people, I tend not to need multiple delete, the use-case tends not to naturally arise and so single DELETE works fine.
In future, and from experience with building REST APIs and hitting the same issues and requirements, like audit, I'd be inclined to use only GET and POST verbs and design around events, e.g. POST a change of address event, though I suspect that'll come with its own set of problems :)
I'd also allow front-end devs to build their own APIs that consume stricter back-end APIs since there's often practical, valid client-side reasons why they don't like strict "Fielding zealot" REST API designs, and for productivity and cache layering reasons.
You can POST a deleted resource :). The URL will be
POST /deleted-records
and the body will be
{"ids": [1, 2, 3]}