1

One of my clients has a Restful API on which I'm supposed to work on that only exposes two verbs: POST and GET. The POST endpoint is used in lieu of the standard Rest verbs: PUT, DELETE, PATCH. The request requires a Strategy enum to be used in order to drive the operation type: so CREATE, UPDATE, DELETE etc.

This is obviously a poor design choice, but I'm having troubles explaining why this is actually a poor design choice. The obvious argument is that it goes against a proper RESTFul design: since HTTP verbs are available why replacing them with a custom object that achieves the same result? But I feel that this is a bit of a weak argument. Is there any stronger point I can make against this design?

1
  • 1
    I am afraid there's no strong argument against the client's solution. If it's well documented and consistent, I don't see any problem with the approach at all, to be honest. Better than trying to frantically follow REST practices but being inconsistent with endpoint design and/or having no documentation at all.
    – Andy
    Aug 28 '20 at 13:02
2

This is obviously a poor design choice

No, it isn't. The world wide web was catastrophically successful using GET and POST (well, and the occasional HEAD request).

A good essay to review here would be Fielding 2009: It is okay to use POST.

POST only becomes an issue when it is used in a situation for which some other method is ideally suited: e.g., retrieval of information that should be a representation of some resource (GET), complete replacement of a representation (PUT), or any of the other standardized methods that tell intermediaries something more valuable than "this may change something."

Limiting your API to GET and POST may be a poor choice, but it isn't an obviously poor choice.

I feel that this is a bit of a weak argument. Is there any stronger point I can make against this design?

The stronger point to make is that, if you use the http method that has the appropriate semantics, then general purpose components can take advantage of their own understanding of those semantics to do useful things.

For example, both PUT and DELETE have idempotent semantics. That means that a general purpose component can know to resend a request when there is no response to the initial request. We don't have to ask if that is okay, or know anything in particular about either the target resource or the payload.

So if you are doing something that is a fit for the semantics of those methods, then you get additional benefits "for free".

But do keep in mind that the value of those benefits, in your circumstances, may be small. The REST interface optimizes "for the common case of the Web".

1
  • 2
    It's worth noting that the Fielding article you quote specifically excludes this scenario we're talking about from being "ok". In other words it is not ok to use POST when PUT or DELETE would be better suited, according to Fielding there. I'm just highlighting this, because your answer seems to imply the opposite (it is right after you say GET and POST are fine for HTTP). Aug 28 '20 at 15:37
1

I would argue as follows:

Consider methods on an object. You would never have

client.DoOperation(operationType);

You can't tell the operation by reading the code, the possible operations are hidden and parameters are fixed across all operations.

Insteads

client.OperationA();
client.OperationB();
... etc

Are prefered. This translates to using the path as the operation indicator. Parameters can be passed in the body or query string

1

Another argument is that PUT and DELETE are repeatable (i.e. idempotent) by design, while POST is not. So if something goes wrong, these operations can be repeated without knowing the content or exact semantics, and without knowing whether the server actually got the request and applied it or not. Also, PUT and DELETE have additional semantics for caching, which POST can't have.

All this makes for an easier API design and error handling on the client for these operations. If there is an error with POST, you basically can only tell the user that something happened, and the server may or may not have done what you wanted.

1

REST is an architectural style. It is not a standard in itself, but RESTful implementations make use of standards.

The HTTP standard expects the GET method to be idempotent (so its response can be cacheable, for example). POST is not expected to be idempotent.

Using POST for everything is like using <span> tags for everything when creating a HTML document. It works, but semantically adds no meaning. Besides, it forces you to massively use styles to change the display of each element. This API forces you to add a verb that otherwise would be unnecessary.

3
  • 2
    I got confused about the need to 'massively use styles' until I went back and realized this was part of your analogy with <span>. Might help to separate this to make your point crystal clear. I made an edit with this suggestion, which you can, of course, undo.
    – joshp
    Aug 30 '20 at 19:48
  • You might also want to make the point that forcing the use of POST informs all clients, proxies, caches, gateways, services, and humans evaluatnig the request that the request is not idempotent. This may be misleading in the case of PUT and DELETE sub-requests.
    – joshp
    Aug 30 '20 at 19:51
  • 1
    @joshp Thank you for your edition. English is not my first language, I think you have improved my answer making it clearer Aug 31 '20 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.