Why you should use standard HTTP methods when designing REST APIs

Suhas Chatekar on February 23, 2017

One of the characteristics of a good REST API is that it uses the standard HTTP methods in a way they are supposed to be used. We hear this all the... [Read Full]
markdown guide
 

I usually think of PUT as a replace.

given an entity A
when I PUT entity B into A
then B will replace A
    and A will be gone forever

A practical example is saving a new file B to the location of an existing file A.

Likewise, I think of PATCH as a merge.

given an entity A
when I PATCH entity B into A 
then A and B will merge to become C
    and C will replace A
    and A and B will be gone forever

A practical example is writing a new field value B to a SQL record A. The resulting SQL record C contains fields from both A and B.

 

Completely agree with you. That perfectly describes what PUT and PATCH should do.

I avoided using that terminology as I have seen that developers new REST style find it difficult to understand that. And then there is this.

Maybe, this is a topic for its own blog?

 

Nice article, I didn't focus on PATCH and idempotency so far.

Reading through the article a question arose: say we have an entity with an 'updated_at' attribute where we store the timestamp of the last update.

Since the 'updated_at' is changed every time we save the entity, saving through a PUT method would break the idempotency, is it correct?

In this case, should we consider to use a PATCH to update that kind of entities?

Thank you!

 

It really depends on how your resources are represented.

One way to keep PUT still idempotent in that case would be to treat updated_at as a server generated value which the client has no control over, which is actually true in most cases. The from a client's perspective, the resource representation they send to the server is same every time and server can respond in an idempotent manner.

 

Ok, that means that a GET shouldn't return the 'updated_at' attribute?
Sorry if I bother :)

Why should it not?

Resource for PUT and GET can look different.

Why should not

Just asking :)

Thank you for your clarification, it was very useful

 

I think idempotence is more important than the verbs.

Using only POST has benefits too.

  • All data is in the body so it doesn't show up in logs.
  • All data is exchanged in the same way in the body, no query parameters.
  • Regular users can't simply copy your API addresses and use them in a browser, because it will always try to GET an URL
 

Yes, idempotence is important but it goes hand in hand with verbs. Browsers and API clients work on the assumption that a POST verb is never idempotent and will behave accordingly so it is important to keep that relationship intact.

I agree with the points you make about advantages of using a POST verb to hide sensitive data.

 

Browsers and API clients work on the assumption that a POST verb is never idempotent and will behave accordingly

Does this mean, they assume other verbs to be always idempotent and also behave accordingly?

I used POST as an example in my statement. What I wanted to say that they will assume what the standard says and behave accordingly.

 

What about checking for authorization before returning such GET requests? Wouldn't it be another way of protecting sensitive data.

I may be misunderstanding your point but it goes without saying that you always properly protect your API, no matter HTTP method is being used.

 

Great article, it is good to know about the specs of the HTTP methods, however you can't rely on every client respecting the specification!

Take a look at OkHttp, a Java HTTP client, very popular with android. OkHttp will potentially repeat your requests on a slow/unreliable connection “aggressively” until it succeeds.. It doesn't matter if it is a request with an idempotent method or not, even POST request are retried until the client gets a valid response. OkHttp mantainers argued that everything should be idempotent by default, and unless the client retries the request agressively under the hood on flaky connections, the only way to know whether the request succeeded or not is to make another request at the application layer, which is not pretty. Initially mantainers suggested users to fix their API backends but later they included a flag to disable this. It's been like that for years now.

 

I have very briefly used OkHttp so thanks for bringing this up.

Without getting into why OkHttp decided to aggressively retry even the POST requests, I find the reasoning presented in the medium article half-baked (for the lack of a right word). When you are in the control of the backend API then you can make decisions that go against the standards like HTTP e.g. making POST requests idempotent. However, a good software developer should consider the following two situations

  1. The API you develop today may only have one application as its client that uses OkHttp to interact with the API. But tomorrow, when you more client applications that do not use OkHttp, how do you deal with that?
  2. Integrating with third-party APIs. In this case, you do not have control over how the third party implements POST operations and aggressive retries by OkHttp can actually harm you.

It is a good news that OkHttp now allows disabling this feature. There are better ways to deal with slow internet connections.

 
 

I started with REST but ended up writing about REST (HTTP API) ;-)

 

Can I ask the difference, for my own understanding? Is there something about this that isn't RESTful?

 

Can I ask the difference? Is there something about this explanation that isn't RESTful, or is it just that REST covers a broader scope than this article?

REST definitely covers a broader scope than this article - the most important being Hypermedia. This article touches upon a tiny subset of REST.

 

@ben there's a couple of encoding errors at the top of this article

 

I have fixed the encoding error now. Thanks for pointing out.

 
code of conduct - report abuse