0

What is the appropriate REST API pattern for a "pure function" that takes an input and returns an output, without side effects?

A trivial case might be a REST API that returns the sum of a list of numbers.

One way of approaching this is, you could think of the function itself as the resource, and use a GET operation to indicate lack of side effects; but then what do you do with the arguments?

A POST could work, but you're not really creating a new resource; you just want an answer back.

2
  • 3
    I think get to indicate lack of side effects seems most idiomatic, but if the arguments are complex then post would seem pragmatic. I'm not sure that the language of REST and pure functional programming will ever sit that happily together. May 3, 2021 at 20:36
  • Basically @SimonN answered your question. May 3, 2021 at 21:41

2 Answers 2

1

The actions embodied by REST center around create (POST), read (GET), update (PUT) and DELETE, operations on a resource. No action or verb in the REST dialect means "calculate". I would even venture to say that this kind of operation is not RESTful to begin with, since you are not interacting with a resource. You are interacting with an algorithm.

The best you can do is a GET to imply there are no side effects to the operation.

Max lengths for URLs can limit the size of arguments sent to the "pure" function, but you still have quite a bit of data to play with. Even so, a GET request eliminates files as input, unless you Base-64 encode them, but again, beware of length limits for URLs.

Use a GET unless the input parameters become too large, then use a POST and forget about REST for this one operation.

I'm actually just leaning towards "forget REST for this one operation" and use whatever gets the job done.

0

One way of approaching this is, you could think of the function itself as the resource, and use a GET operation to indicate lack of side effects; but then what do you do with the arguments?

You imagine the function results as a resource; the arguments are encoded into the identifier.

On the web, you will normally see this as an HTML::Form with a GET action; data collected by input controls are encoded as key value pairs and encoded into an application/x-www-form-urlencoded document which becomes the query part of the identifier.

More generally, we use a URI Template to describe how to encode arguments into the URI.

Two big advantages of using this pattern:

  • your results are easily cached, just like any other page on the web
  • GET has safe semantics, which means that we can recover when an http message is lost on an unreliable network.

When we can't use this pattern (for instance, because the "arguments" are too complicated to describe using an identifier), then we fall back to putting the arguments into the message-body of the request.

That eliminates GET as an option, because a "payload within a GET request message has no defined semantics." You can't guarantee that the body will make it through all of the general purpose components between your client and your server.

We don't, yet, have a good general purpose standard for GET-with-a-body. The HTTP working group "adopted" (in 2020) a proposal to address this, but it will still take some time to work through the process of becoming a standard.

So that leaves POST; it is okay to use POST. It gets the job done. General purpose components don't help very much, but they also don't get in the way.

A POST could work, but you're not really creating a new resource

Doesn't matter - nothing in the standard says that POST has to create a new resource. If you do create a new resource, the standard tells you how to communicate that via metadata.

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.