18

I am researching before starting to work on an API for a web-service I am building. The goal is to be very quick and easy to adapt and use for other developers but fairly hidden for clients using a collection of Webapps to make calls to the service behind the API.

It is the first time making an API for more than internal use and I am now wondering researching the standards out there if I should follow RESTful recommendations or rather just go (my instinct) with POST Requests and a JSON-body that holds all the necessary information.

My reasoning against using GET / HTTP-Verbs:

  • The service has fairly fine grained Read/Write control for every single User and DB items. So even a simple LIST request has to be checked not only for credentials but has to do a bunch of internal validation procedures to see if the client is allowed to ask this questions for this particular piece of data.
  • easy implementation: while coding I usually am happy to not have to hop between GET Urls and POST or PUT bodies to get my JSON payload over the line. Appending them to the URL if it is a GET request or into the body if it is a POST or a PUT. So it feels less of a hassle to just go with POST. but I see that is very much my personal taste rather than true for everybody - I am just damn lazy ;-)
  • not really a valid point because we use SSL anyhow, but https://stackoverflow.com/questions/198462/is-either-get-or-post-more-secure-than-the-other#1744404 suggests that it at least, in theory, it might be a little more secure to not force too much sensitive stuff into the URL. In particular, if even READ/LIST requests are considered sensitive for a service, it feels at least a little weird to operate within the URL.

my reasoning for using GET / HTTP-Verbs:

  • Compatibility: Standards are great. And RESTful APIs still seem the most common ones. GET can be easily tested or used by clients from a browser (not sure if that is really a plus, but it might turn out as one)
  • RESTful forces me into a fine-grained separation of concerns through not only URL but also the HTTP verbs (GET/POST/PUT etc). Only using POST I could do the same through URL or early JSON parsing.
  • this blogpost explains a bit about the issues, I found very helpful

Are there any other strong reasons for using the full variety of HTTP verbs like for example REST principles would suggest?

I cannot find any API that does not use different HTTP Verbs. So I guess there must be very strong reasons for that. I suspect the reasons mentioned in the blogpost to be the most relevant, but wonder if there is more to it and if there are other solutions than the one proposed there (first POST, then serving a new GETable resource and returning the URL)

note

this question is similar to mine but comes from a slightly different angle: Is it bad to use POST only on an API?

Adam Miklosi
  • 135
  • 1
  • 2
  • 7
gaugau
  • 321

6 Answers6

14

"What reasons are there AGAINST using only POST HTTP verb in an API?"

You have answered your own question:

The goal is to be very quick and easy to adapt and use for other developers...

If your goal is for other developers to quickly understand and use your API, then use generally accepted practices that most developers would expect. It's as simple as that.

To review your reasons for using POST:

  • I think it would be very strange for a list operation to use POST
  • Your laziness in implementing the API will have a direct cost when other developers begin using it and wonder why every operation requires POST
  • Any hypothetical security risks in using GET are far outweighed by arguments for standards

If you want to experiment with an API that only you will ever use, then feel free to do whatever you wish. But if you want other developers to use it then please save us the frustration and just use the standards.

Dan Wilson
  • 3,143
8

If you want to make things easy for developers using your api, don't worry about the RESTfulness of various verbs.

Publish A Client

If you publish a client then GET or POST is an implementation detail no-one cares about. If you force the developer to write their own client they need to read you docs to find out whether it's GET or POST.

Robert Harvey
  • 200,592
Ewan
  • 83,178
7

I added this comment here, but I wanted to elaborate on my reasoning in an answer.

When we talk about APIs, usually we mean remote APIs, especially HTTP REST APIs. But API stands for Application Programming Interface, so it may mean just a collection of classes/functions (a library).

In my opinion, a remote API is basically an API that is accessed remotely, and it should be designed in a similar way to a "local" API (a library).

If a library contains well defined methods (with well chosen names and parameters), a remote API should be designed in a similar way.

A library API doesn't have the concept of HTTP Method, just a name and parameters, so I think that in a remote API we could ignore the HTTP Method and just use a good name and parameters for each end-point (method).

For the HTTP Method I would choose POST, because we need to choose one, and POST is the most typical method that allows body.

A library method could be:

class Documents {
  DocumentSearchResult findDocuments(DocumentFilter);
}

The equivalent remote API method could be:

@Path("documents")
class Documents {
  @POST @Path("findDocuments")
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  DocumentSearchResult findDocuments(DocumentFilter);
}

Note that the remote API needs to expose the class/instance and method names via @Path. Maybe a framework could deal with this automatically, so neither @Path nor @POST are necessary (or even the MediaType). But that's another story. Anyway, in that case, the remote API would be declared like this (yes, like the local library interface):

class Documents {
  DocumentSearchResult findDocuments(DocumentFilter);
}

When calling these methods, we would do:

// Local library API usage (pseudo-code, looks like Java)
DocumentSearchResult result = documents.findDocuments(filter);

// Remote API usage (pseudo-code, looks like Dart)
DocumentSearchResult result = await http.post("documents/findDocuments", body: filter);

We could even hide that we're doing a POST, since we want to ignore that, so we could wrap those http calls in a helper function like this, to make it even more similar to a local API call:

// Remote API usage using helper function (pseudo-code)
DocumentSearchResult result = await call("documents.findDocuments", filter);

Having reached this point, we could take it a step further and create a class that wraps this remote call and do this (yes, almost like a local library call):

// Remote API usage using helper class (pseudo-code)
DocumentSearchResult result = await documents.findDocuments(filter);

That could be done manually or by some code generator plugin. But that's another story.

5

GET requests are supposed to be idempotent if your using them to post date then it will violate this and be unexpected by users of your api.

Rob
  • 167
2

There are no reasons to use anything but POST.

GET can be 1-2 milliseconds quicker but this difference in performance is almost always negligible.

POST more secure: CSRF is only possible with GET.

Following bad standards? REST is a bad standard: it is too verbose and insufficiently descriptive at the same time.

Yuriy N.
  • 121
1

I find the POST and PUT endpoints are a little more awkward to test using Curl or a browser's address bar. It's not a huge issue, I admit, but it does exemplify why it's OK to let GET do what it's good at.