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?

8
  • Is this a published API or an internal API? In other words do you expect anyone outside your own team to write code that uses this API? If it's not published you have a lot more flexibility to make up and change your own rules and conventions.
    – bdsl
    Commented Nov 1, 2021 at 17:18
  • 3
    At some point, you just need to be pragmatic. If the payload doesn't fit in the URL and you have to resort to unconventional practices to make it work as a GET, maybe you should just make it a POST. Commented Nov 1, 2021 at 17:29
  • Does this answer your question? REST: Can I use POST request to read data?
    – Rik D
    Commented Nov 1, 2021 at 17:39
  • @bdsl internal API
    – jcollum
    Commented Nov 1, 2021 at 19:58
  • @RikD sort of, there's a few options but really it seems like a JSON RPC is the best option since REST isn't well built for this, which is disappointing. The answer I came away with was "fake REST out or use an RPC".
    – jcollum
    Commented Nov 1, 2021 at 20:39

2 Answers 2

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.

6
  • I think I decided that REST is not suited to this and a JSON RPC is going to be a better alternative, if possible. I just hate this thing we do where we go "here's a spec that you should follow!! oh wait, no not this time though". Really, if there's a very common exception to a spec is it a good spec? It would be preferable to POST the data and get a response that is the "location" of the calculation result (which could be cached). But that means two steps.
    – jcollum
    Commented Nov 1, 2021 at 21:59
  • I believe the HTTP spec says that GET must be safe and idempotent, it doesn't say that POST must not be either of those things. Why would it say that? Being idempotent is not a bad thing.
    – bdsl
    Commented Nov 1, 2021 at 22:31
  • "Generally – not necessarily – POST APIs are used to create a new resource on the server. So when we invoke the same POST request N times, we will have N new resources on the server. So, POST is not idempotent." restfulapi.net/idempotent-rest-apis -- in other words every POST is supposed to (typically) create a new resource. That's not idempotent since a billion calls to POST could crash a database. A billion calls to GET will just get you the same resource a billion times. MDN agrees.
    – jcollum
    Commented Nov 1, 2021 at 22:43
  • 5
    @jcollum I think you're being a tad too dogmatic about this. REST is good when you're dealing with resources, which isn't your case here. As you already mentioned, you're essentially running a remote procedure on a server using a large payload, this is a perfectly good use of the POST verb. Commented Nov 1, 2021 at 23:22
  • "running a remote procedure on a server" -- sure sounds like an argument for not using REST at all and using RPC instead.
    – jcollum
    Commented Nov 2, 2021 at 18:29
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.
1
  • Are there any significant downsides to using a JSON RPC call instead of HTTP? That seems more semantically in line with what is happening.
    – jcollum
    Commented Nov 2, 2021 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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