0

We have an internal library that does a calculation based on several datapoints. There is a fair bit of data required for the calculation, about 5kB in total. I'd like to make this an API endpoint for easier use across the org. But the calculation is idempotent and does not create any resources. I think this means it should be a GET verb.

I see three options:

  • use GET, put all the information required for the calc in the URL: this risks hitting character limits and it will mean JSON encoding data for the URL, which just seems weird
  • use GET, put all the information required for the calc in the headers: I guess this would work but it seems like an odd thing to do
  • use a POST verb, put the data in the POST body: the calc is repeatable and idempotent so a GET verb feels like the right thing to do, there is no modification of resources happening

Are there any options I'm not seeing?

jcollum
  • 229

2 Answers2

10

Use POST. Yes, it's not ideal, but you're running into technical limitations using a GET request for such a large payload. You mentioned URI length limitations, and (most) web servers limit the size of headers they accept. Trying to deal with all those things is likely to be a maintenance nightmare. Just imagine having to deal with differently configured software, proxies, and so on. And I don't know if that's likely or even possible in your case, but imagine needing more input data in the future. Even if you manage to make things work now, it may not stay that way.

An ugly solution is better than one that may break at any moment.

Jasmijn
  • 1,904
1

You seem to be applying REST-based rules for a non-REST service.

REST is centered around the idea of "resources" (things/documents/objects/...), and "naming" the resources as "URLs".

If your service were to follow the REST concept in its fullest, the input data should be treated as first-class resource, i.e. hosted under some URL. And the state transfer of computing some results should be made available as a link in that input data resource. So, you'd e.g. end up with

  • POST data input, get back its URL,
  • GET the URL to retrieve the "Computation" link,
  • GET the results document from that linked URL.

But this does not match your intentions, so forget about the REST approach and all the rules that are derived from it.

Of course, the generic HTTP rules (e.g. GET being idempotent) still apply. And of the standard HTTP verbs, POST is the one to be used in cases where the others aren't applicable for one cause or another.

So, treat this service as a non-REST service and use the POST verb.

Addendum:

Your original approach violates REST in multiple aspects:

  • It doesn't treat the input data as first-class resources.
  • In the URL-embedding version, it relies on a specific URL construction syntax, while according to REST, URLs should be opaque, never constructed synthetically nor parsed, and only obtained from server responses.
  • In the URL-embedding version, the URL hardly names a relevant domain concept, something that deserves the "resource" labelling. It's like giving a URL name to the result of computing 3*7+4*2, but not to 3*7+4*2.
  • In the header-embedding version, GETs aren't idempotent, as conceptually different results are obtained from the very same URL, only distinguished by header values.