Are DELETE/PUT http verbs needed? - rest

I don't see a huge benefit of designing a REST API service that uses PUT and DELETE to update and delete data. These 2 verbs can be easily replaced by using a POST and a unique url.
The only benefit I see of using PUT and DELETE is it cuts down the number of url's that the REST API service uses which isn't much. Are there other benefits that I'm overlooking?

This actually has not so much to do with REST, but more with the Hypertext Transfer Protocol (HTTP).
The basic idea of HTTP is that you perform a certain action (one of the HTTP methods, such as GET, POST, PUT and DELETE) on a certain resource (identified by its URL). So if you start deviating from that by adding the action into the URL (such as http://example.com/api/books/123/delete) and using a different HTTP method, you are violating the HTTP protocol.
The downsides of this might not be instantly visible (because it will still work), and might be limited if you are only using the API by yourself. However, if other programmers are using the API as well, you are creating certain expectations by stating that you have a RESTful HTTP API while you are actually not adhering to the protocol.
For instance, if calling GET /api/books/123 returns a representation of the book resource, a developer expects to be able to call PUT on that same URL to update the information on that book, and DELETE to remove the book alltogether. (of course, if he does not have permissions to do that, you don't actually remove the book but you return a 403 'Forbidden' or 405 'Method Not Allowed' status code - which are also part of the HTTP specification)
However, if you deviate from the protocol (basically inventing your own protocol), you will have to describe somewhere that instead of calling DELETE /api/books/123 developers have to call POST /api/books/123/remove/the/book. They will have to be aware of all your API's custom rules because you are not following the standard.
Another good point is made by Darrel Miller in his answer. The HTTP methods all have a certain meaning and also certain characteristics. For instance, GET is supposed to be a safe method, used to retrieve information without making any changes on the server side. And PUT and DELETE are idempotent, which means that (even though they are not safe methods like GET) you can make as many requests as you like without any unwanted side effects (deleting a book one or ten times has the same effect: the book is gone). POST however is not idempotent: if you do ten POST requests to create a new book, you will most likely end up with 10 duplicate book entries.
Because of these characteristics, developers and tools are able to make certain assumptions. For instance, a search indexer such as Googlebot will only do GET requests, in order to not break anything on the server. However, if you would be violating the HTTP specification by having a URL http://example.com/api/books/123/delete in order to delete a book, you might notice at one day that your database is completely empty because Google has been indexing your site. That wouldn't be Google's fault but yours, because you didn't follow the specification.
So to make a long story short: using a protocol or standard (such as HTTP) sets certain expectations, and if you then deviate from the protocol you will create unexpected behavior and possible unwanted side effects.

It is not required to use PUT and DELETE to get the benefits of a REST based system.
Using the more precise methods can be advantageous in certain cases. Usually it is intermediary components that take advantage of the semantics. PUT and DELETE are idempotent methods, so if some generic component receives a 503, in theory it could retry a PUT/DELETE until it gets a successful response. With a POST method, the intermediary can't do that.
With a DELETE method a client knows not to send a body. With a PUT, it knows to send a complete representation. With a POST method, you need to communicate to the client how to make the request in some other way, like a link relation.

You can live without PUT and DELETE.
This article tells you why: http://www.artima.com/lejava/articles/why_put_and_delete.html
..BUT (quote from Fielding): "A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field. Workarounds for broken implementations (such as those browsers stupid enough to believe that HTML defines HTTP’s method set) should be defined separately, or at least in appendices, with an expectation that the workaround will eventually be obsolete. [Failure here implies that the resource interfaces are object-specific, not generic.] "
(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven)

Related

Modelling a endpoint for a REST API that need save data for every request

A few time ago I participate from a interview where had a question about REST modelling, and how the best way to implement it. The question was:
You have an REST API where you expose a method to consult the distance between two point, although you must save each request to this method to expose the request history.
And I was questioned about which HTTP method should be used on this case, for me the logic answer in that moment was the GET method (to execute the both actions). After this the interviewer asked me why, because since we are also storing the request, this endpoint is not idempotent anymore, after that I wasn't able to reply it. Since this stills on my mind, so I decided to verify here and see others opinions about which method should be used for this case (or how many, GET and POST for example).
You have an REST API where you expose a method to consult the distance between two point, although you must save each request to this method to expose the request history.
How would you do this on the web? You'd probably have a web page with a form, and that form would have input controls to collect the start and end point. When you submit the form, the browser would use the data in the controls, as well as the form metadata and standard HTML processing rules to create a request that would be sent to the server.
Technically, you could use POST as the method of the form. It's completely legal to do that. BUT, as the semantics of the request are "effectively read only", a better choice would be to use GET.
More precisely, this would mean having a family of similar resources, the representation of which includes information about the two points described in the query string.
That family of similar resources would probably be implemented on your origin server as a single operation/route, with a parser extracting the two points from the query string and passing them along to the function as arguments.
the interviewer asked me why, because since we are also storing the request, this endpoint is not idempotent anymore
This is probably the wrong objection - the semantics of GET requests are safe (effectively read only). So the interview might argue that saving the request history is not read only. However, this objection is invalid, because the semantic constraints apply to the request message, not the implementation.
For instance, you may have noticed that HTTP servers commonly add an entry to their access log for each request. Clearly that's not "read only" - but it is merely an implementation detail; the client's request did not say "and also log this".
GET is still fine here, even though the server is writing things down.
One possible objection would be that, if we use GET, then sometimes a cache will return an previous response rather than passing the request all the way through to the origin server to get logged. Which is GREAT - caches are a big part of the reason that the web can be web scale.
But if you don't want caching, the correct way to handle that is to add metadata to the response to inhibit caching, not to change the HTTP method.
Another possibility, which is more consistent with the interviewer's "idempotent" remark, is that they wanted this "request history" to be a resource that the client could edit, and that looking up distances would be a side effect of that editing process.
For instance, we might have some sort of an "itinerary" resource with one or more legs provided by the client. Each time the client modifies the itinerary (for example, by adding another leg), the distance lookup method is called automatically.
In this kind of a problem, where the client is (logically) editing a resource, the requests are no longer "effectively read only". So GET is off the table as an option, and we have to look into the other possibilities.
The TL;DR version is that POST would always be acceptable (and this is how we would do it on the web), but you might prefer an API style where the client edits the representation of the resource locally, in which case you would let the client choose between PUT and PATCH.

Using GET verb to update in rest api?

I know the use of http verbs is based on standard specification. But my question if I use "GET" for update operations and write a code logic to update, does it create issues in any scenario? Apart from the standard, what else could be the reason to use these verbs for a specific purpose only?
my question if I use "GET" for update operations and write a code logic to update, does it create issues in any scenario?
Yes.
A simple example - suppose the network between the client and the server is unreliable; specifically, for a time, HTTP responses are being lost. A general purpose component (like a web proxy) might time out, and then, noticing that the method token of the request is GET, resend the request a second/third/fourth time, with your server performing its update on every GET request.
Let us further assume that these multiple update operations lead to an undesirable outcome; where do we properly affix blame?
Second example: you send someone a copy of the link to the update operation, so that they can send you a request at the appropriate time. But suppose you send that link to them in an email, and the email client recognizes the uri and (as a performance optimization) pre-fetches the link, triggering your update operation too early. Where do we properly affix the blame?
HTTP does not attempt to require the results of a GET to be safe. What it does is require that the semantics of the operation be safe, and therefore it is a fault of the implementation, not the interface or the user of that interface, if anything happens as a result that causes loss of property -- Fielding, 2002
In these, and other examples, blame is correctly affixed to your server, because GET has a standardized meaning which include the constraint that the semantics of the request are safe.
That's not to say that you can't have side effects when handling a GET request; "hit counters" are almost as old as the web itself. You have a lot of freedom in your implementation; so long as you respect the uniform interface, there won't be too much trouble.
Experience report: one of our internal tools uses GET requests to trigger scheduling; in our carefully controlled context (which is not web scale), we get away with it, and have for a very long time.
To borrow your language, there are certainly scenarios that would give us problems; but given our controls we manage to avoid them.
I wouldn't like our chances, though, if requests started coming in from outside of our carefully controlled context.
I think it's a decent question. You're asking a hypothetical: is there any value to doing the right other than that's we agree to use GET for fetching? e.g.: is there value beyond the fact that it's 'semantically nice'. A similar question in HTML might be: "Is it ok to use a <div> with an onclick instead of a <button>? (the answer is no).
There certainly is. Clients, servers and intermediates all change their behavior depending on what method is used. Even if your server can process GET for updates, and you build a client that uses this, your browser might still get confused.
If you are interested in this subject, don't ask on a forum; read the spec. The HTTP specification tells you what clients, servers and proxies should do when they encounter certain methods, statuses and headers.
Start at RFC7231

Why does the GitHub API use a PUT request for starring a repository?

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.

REST: What is difference between GET and DELETE, when we can implement same functionality in both?

In REST Web Services we have GET AND DELETE methods.
Generally we read GET is to get data from server like "getCountriesName" and DELETE is used to call resource which deletes particular object like "removeOrganization".
But if i implements DELETE to "getCountriesName" then it successfully returns country name.
So how both are different? Any real-time scenario?
It is technically possible, but if you make that way, then you are not following the REST standards. I would recommend to use delete to remove resources and get to query them
Looking at the Richardson Maturity Model, if you're aiming to achieve at least level 2 of REST, you'll end up with resources (Country) and HTTP VERBS:
GET /api/countries/{id}
which would also return the country's name, among other parameters.
You could also issue a DELETE request towards the same URL, provided there's an endpoint that supports this - in the backend you'll usually have methods that allow a certain HTTP VERB on them. The details of the implementation depend on the language you're using, for example in C# you would have a method with mostly the same signature, but a different attribute on top of it, like [HttpDelete]).
Thinking in terms of methods (getCountriesName/removeOrganization) is not RESTful at all, but rather SOAP/RPC.
How your service handles requests is completely up to you. You could basically create new resources on receiving GET requests or delete things using OPTION, though I highly recommend to not do so as this does not adhere to the backing protocol (HTTP in this specific case) and thus violates a basic REST constraints. Note further that a RESTful service should always adhere to and respect the supported protocols.
According to RFC 7231, one of the major differences between GET and DELETE is, that the latter one removes an association from a given resource and its functionality and also that the returned response is not cachable. This may or may not remove the data physically, the effect on consecutive DELETE or GET operations is, however, that the deleted resource should not be obtainable further. A consecutive DELETE request is issued to the server regardless of any previous request. If the resource was deleted before, the service should notify the client with a propper 404 Not Found error response if no new resource was created in between two delete operations on the same resource.
GET responses, on the other side, are cachable and thus may save work on the server by returning the result from a previous request directly from the (proxied) cache rather then issuing the request to the server. This can be fine-grained with propper cache-header settings.
The type of HTTP method to be used is more of a convention and a practice to be followed. This would give wrong information when the API s are exposed to the external systems
Refer to the blog post for detailed info

PUT POST being idempotent (REST)

I don't quite get how the HTTP verbs are defined as idempotent. All I've read is GET and PUT is idempotent. POST is not idempotent. But you could create a REST API using POST that doesn't change anything (in the database for example), or create a REST API for PUT that changes every time it is called.
Sure, that probably is the wrong way to do things but if it can be done, why is PUT labeled as idempotent (or POST as not) when it is up to the implementation? I'm not challenging this idea, I'm probably missing something and I ask to clear my understanding.
EDIT:
I guess one way to put my question is: What would be the problem if I used PUT to make a non-idempotent call and POST to do so?
You are right in pointing out there is nothing inherent within the HTTP protocol that enforces the idempotent attribute of methods/verbs like PUT and DELETE. HTTP, being a stateless protocol, retains no information or status of each request that the user makes; every single request is treated as independent.
To quote Wikipedia on the idempotent attribute of HTTP methods (emphasis mine):
Note that whether a method is idempotent is not enforced by the
protocol or web server. It is perfectly possible to write a web
application in which (for example) a database insert or other
non-idempotent action is triggered by a GET or other request. Ignoring
this recommendation, however, may result in undesirable consequences,
if a user agent assumes that repeating the same request is safe when
it isn't.
So yes, it is possible to deviate from conventional implementation, and rollout things like non-changing POST implementation, non-idempotent PUT etc. probably with no significant, life-threatening technical problems. But you might risk upsetting other programmers consuming your web services, thinking that you don't know what you're doing.
Here's an important quote from RFC2616 on the HTTP methods being safe (emphasis mine):
Implementors should be aware that the software represents the user in
their interactions over the Internet, and should be careful to allow
the user to be aware of any actions they might take which may have an
unexpected significance to themselves or others.
In particular, the convention has been established that the GET and
HEAD methods SHOULD NOT have the significance of taking an action
other than retrieval. These methods ought to be considered "safe".
This allows user agents to represent other methods, such as POST, PUT
and DELETE, in a special way, so that the user is made aware of the
fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects, so
therefore cannot be held accountable for them.
UPDATE: As pointed out by Julian, RFC 2616 has been replaced by RFC 7231. Here's the corresponding section.
So when you publish a web service as a PUT method, and I submit a request that looks like:
PUT /users/<new_id> HTTP/1.1
Host: example.com
I will expect a new user resource to be created. Likewise, if my request looks like:
PUT /users/<existing_id> HTTP/1.1
Host: example.com
I will expect the corresponding existing user to be updated. If I repeat the same request by submitting the form multiple times, please don't pop up a warning dialog (because I like the established convention).
Conversely, as a consumer of a POST web service, I will expect requests like:
POST /users/<existing_id> HTTP/1.1
Host: example.com
to update the corresponding existing user, while a request that looks like:
POST /users/<new_id> HTTP/1.1
Host: example.com
to raise an error because the URL doesn't exist yet.
Indeed, an implementation can do anything it wants. However, if that is incorrect according to the protocol spec, surprising things might happen (such as as library or intermediary repeating a PUT if this first attempt failed).
hope the link helps to you:HTTP Method idempotency
Be careful when dealing with safe methods as well: if a seemingly safe method like GET will change a resource, it might be possible that any middleware client proxy systems between you and the server, will cache this response. Another client who wants to change this resource through the same URL(like: http://example.org/api/article/1234/delete), will not call the server, but return the information directly from the cache. Non-safe (and non-idempotent) methods will never be cached by any middleware proxies.