Functional REST

On the drive home a while back, I was thinking about the REST model, which is resource-oriented. Everything in the system is a resource. The pointers are all references to resources. The allowed operations are variations on CRUD, and no more. Well, not much more, if you’re doing it right.

So the next obvious thing is to make functions first-class objects, er… resources, as well.

I haven’t thought it all the way through, but I think that offers some interesting possibilities.

  • The resources that a client uses GET PUT DELETE on are, in fact, stateless functions.
  • The stateless nature of functional programming fits perfectly with the stateless nature of REST services.
  • Someone who has the right permissions could PUT their own function definition into the system, and then POST data to invoke it.
  • The functional language could reference other functions, naming them by URI.
  • Functions in the system could take advantage of all the meta-patterns that functional programming provides, like mapping, reducing, filtering, composing, joining, etc. I bet you could even generate lambda functions.
  • URIs are long, so you’d probably want some sort of aliasing feature πŸ˜‰
  • The input for POSTing could be a combination of the usual resource representation, like JSON, and URI references to other resources.
  • Monitoring would be hell. I think you’d want to have some sort of CPU meter and an automated kill switch, depending on how much leeway you wanted to give your users.
  • The access control model would be interesting, since a wide range of data resources might be involved.

Interestingly, this is kind of along the lines of a system I put together about a year ago, where I used Java reflection to map URIs and POST bodies to a Command-pattern API that we have internally. At the time, I didn’t really really think about it as a “functional” (well, it was functional in the sense that it worked and people were really happy with it). I was just mapping URIs to the Command objects in the API using Java reflection. I didn’t think too hard about the big picture, so I don’t think it counts.

It’s kind of an interesting idea. I did a search, and haven’t seen any other references to “functional REST”, but I’ll keep my eyes open. With all the functional programming wonks running around, it’s just a matter of time before someone puts a system like that together. …Someone probably has already.

Advertisements

11 Comments

Filed under REST

11 responses to “Functional REST

  1. Eric J. Bowman

    “Someone who has the right permissions could PUT their own function definition into the system, and then POST data to invoke it.”

    You mean “…and then GET to invoke it.” The notion of a resource being a stored procedure is quite common in REST discussions. For example, if you’re using an XML DB, a user can PUT some XQuery code into a new cell (URI), then make a GET call to the URI to execute the code.

    Parameters may be passed to the XQuery code via the URI using ‘;’ and/or ‘?’, and maybe the x-www-form-urlencoded media type identifier from a -based HTML page. Depending on the media type of the output, parameters may be passed via the URI using ‘#’ (SVG, for example, does nifty things with fragments — ‘document-stored procedures’ is how I think of it).

    The key notion here is to invoke your stored procedures using GET, not POST. Requests to invoke the procedure are idempotent (making them inappropriate for POST, the semantics of which are vague aside from being non-idempotent), and the results ought to be easily cacheable, so use GET just like you’d do with a search interface.

    Only use POST (or PUT) for requests that change the state-engine your resource is modeling, i.e. to alter the XQuery code in an XMLDB cell. If your requests are for different representations which may be generated by the modeled resource depending on input values, use GET and one or more of ‘;’, ‘?’ and/or ‘#’ in the URI.

    • roby2358

      GET sounds like a perfect fit for executing complex queries like you suggest. But I never guaranteed that the functions I’d like to save would be “safe”. Even if the state of the function doesn’t change, the function might alter the state of other resources identified in the input, making the function inherently “unsafe”.

      Also, I do worry about tweaks in the URI to switch between the result of a GET being the resource instance, or the execution of the instance. Seems like that’s changing the verb to suit our intention, and GET is the wrong verb to overload that way.

      I also don’t want to restrict myself to the notation available in a URI or query string. JSON is a rich object-based description, and it’s standard and easy, and I’d like to be able to mix and match inputs and outputs from resource APIs and the functional API. So I should be able to GET a resource from somewhere, and then just turn around and POST it in the body somewhere else, without forcing a coversion from JSON to some sort of “matrix” notation.

      Finally, I want to leave the door open for a rich hyper-notation of the input. It should be able to intermingle URIs and static data in the message body, and again I think you’d have to rely on a structural object syntax like XML or JSON for that.

      PUTing complicated queries and GETing their results is a good idea & I hadn’t really thought of that. But I’m not convinced that GET is going to work for what I’m mulling over. Even so, using POST is drifting out of the REST world — I think you’d have to add a lot of richness to the functional REST API to allow for compositing of functions, hyperlinking resources in the input and output, really working the functional concepts, and so forth. Otherwise it would just be another dumb way to force an RPC syntax into a REST-ish API.

  2. Eric J. Bowman

    “Even if the state of the function doesn’t change, the function might alter the state of other resources identified in the input, making the function inherently ‘unsafe’.”

    The only thing REST says about GET, is that the client can’t be held liable for any changes that may be made as a result of that GET — updating a hit counter, for ancient example. That a GET changes the value of some other resource, doesn’t make GET unsafe on the requested resource.

    “Also, I do worry about tweaks in the URI to switch between the result of a GET being the resource instance, or the execution of the instance. Seems like that’s changing the verb to suit our intention, and GET is the wrong verb to overload that way.”

    Huh? The form is the basic building-block of REST architecture:

    GET /form

    –> 200 OK
    form method=’get’ action=’#’>
    input type=’button’>
    option value=’x’>y/option>
    /input>
    /form>

    Submitting the form results in GET /form?x=y. This is a self-documenting, i.e. hypertext-driven, interface. Google’s homepage uses action=’/search’ and redirects /search to the homepage (sorta). Close to REST but no cigar, yet fundamentally sound nonetheless.

    So I’m not understanding the basis of your argument.

    • roby2358

      > That a GET changes the value of some other resource, doesn’t make GET unsafe on the requested resource.

      That’s a good point, both in the broader context and on this topic.

      > Close to REST but no cigar, yet fundamentally sound nonetheless.

      Exactly my point… that would work, but I’m more noodling around with building a REST service, rather than a plain HTTP service. I’m wondering about the intersection of the principles of REST with the principles of functional programming. I could sit down and write a Servlet that accepts a POST to save a block code in some scripting language, and GET to execute it, and go home. I could do that faster than I could post to this blog. But that’s not the point.

      In the REST model, you want to be strict with GET. If you have to play fast and loose, POST is a better verb for that. Even searches are a tricky problem for REST, and there are lots of ways to rationalize it, some ways better than others. But if we take all the problems with search and add arbitrary function invocations to the mix, then we’ve really defeated the purpose.

      The HTTP spec for POST provides that cryptic allowance for “data handling processes”, which is kind of like the HTTP equivalent of the 9th Amendment, so in playing with this model, I’d still be a lot more comfortable putting execution under POST rather than GET.

  3. Tommy Sullivan

    I have thought of this too. U can define resources as stateless functions and give them urls. U can provide many implementations (j’s, java, .net). Function definitions ultimately bind to identifiers which are either passed in or assumed to exist in some name resolution scope. One can use closures to define names in the calling client’s existing function scope, and as well one can define json objects and the object property names can be eval’ed as vars within the scope of a “function provider” function, whose job it is to retrieve functions and then invoke them with passed parameters from the perspective of the calling client function. This allows URL based dependency injection at a function level. Also, remote invocation is possible in many ways, but posting to function URL is not the way i think. Need to post rather to a resource who is a function invocation container and point to the URL of the desired function graph to invoke.

    • roby2358

      > Need to post rather to a resource who is a function invocation container and point to the URL of the desired function graph to invoke.

      Here’s what I’m kicking around:
      * POST to a function container URI to create a new function (if you want to brand it with an id generated by the server… otherwise just use PUT)
      * PUT to the function URI to update the definition of the function
      * GET the function URI to get the definition of the function
      * POST structured data (JSON) to the function to process that data, per the HTTP spec for the POST method

      Now, you could split out the function from an invocation resource you suggest, but I don’t think that’s necessary…. I think that you can use the “data processing” sense of POST to process structural data, and get back the processing result.

      I guess I’m going for the same sense as in true OO where an Object does it all… rather than providing a separate Handler or Controller or Runner or Invoker, you just invoke the object itself. That’s sort of like the various dynamically-typed scripting language, where the distinction between a function and a map (or dictionary πŸ˜‰ ) gets blurred.

      • Tommy Sullivan

        My thought is that every addressable resource is a Conceptually unique resource, and that the description of a resource should not vary with respect to the verb being applied in any way.

        This would not disqualify your suggestion about posting to a function to invoke it (presumably the return value is a distinct uri that can be obtained with a GET). However to be consistent with the above predicate, such a design would necessarily make the description of *what that resource is*, at the function uri, more vague. Example, “the resource is a function definition that can be retrieved with get, replaced with put, but posting is not a way to update the function definition, rather it is a means of implying that the http server execute the function”.

        If there is something like http://functionExecutions that is posted to, then we have two less vaguely described resources and the verbs of each take on their more familiar function and the intent is clear.

        Also, it makes sense that a function *definition* be defined in one place, but not always *executed* in that same place.I have thought of this too. U can define resources as stateless functions and give them urls. U can provide many implementations (j’s, java, .net). Function definitions ultimately bind to identifiers which are either passed in or assumed to exist in some name resolution scope. One can use closures to define names in the calling client’s existing function scope, and as well one can define json objects and the object property names can be eval’ed as vars within the scope of a “function provider” function, whose job it is to retrieve functions and then invoke them with passed parameters from the perspective of the calling client function. This allows URL based dependency injection at a function level. Also, remote invocation is possible in many ways, but posting to function URL is not the way i think. Need to post rather to a resource who is a function invocation container and point to the URL of the desired function graph to invoke.

      • Tommy Sullivan

        Also, you appeal to OO but this is entitled functional rest, no? πŸ™‚ I found this page by googling functional rest and am happy to see another person has been thinking along the same lines.

        My line of thought has lead me to JavaScript as an implementation, so that servers and clients alike can amorphously move functions around and execute them wherever. I have tinkered with the thought of a browser which is also an http server so it can host local resources and post urls to them to external http servers which can then call back, perhaps several server hops later, on an “as-needed” basis, allowing for representational variance at *that time* rather than posting representations directly from the browser up front. With JavaScript try hosting resources each with a single anonymous function expression in them. This allows even function naming and identifier binding to be up to the http client. This way object models can be graphs of hyperlinks to anonymous functions and dependency resolution can be layered in. Cool stuff man.

      • roby2358

        > Also, you appeal to OO but this is entitled functional rest, no?

        Heck, we’re both blurring the line by calling a function a resource πŸ˜‰ We might be better off just deciding to live in Verb-land or Noun-land and call it good! lol!

        My thinking is actually changing as I read your reply — you’ve gone down this path further than I have. It occurred to me that I wasn’t thinking about a bunch of functions as entities of a single resource type, like “/function/<function-name>”.

        But I see the two approaches as more or less isomorphic. So the following do the same thing in different ways. In the end you send in structured data, and you get back structured data (i.e. nested data rather than just name-value pairs, although that would probably be OK too).

        + POST data in the request body to URI and return JSON in the response body
        + GET name-value pairs in the query string and get JSON in the response body
        + GET with the function URI and parameters in the query string and get back JSON in the response
        + GET or POST data as above and get a Location in header or body, then GET that location to get the data.

        I think all of those are OK by REST, and it’s just a matter of preference and usage which way you go.

        I think Microsoft started down this path with “agents” that get slung around. But it seems like the efforts to get into this get bogged down with authorization problems. But I agree with you, dynamically creating functions and handing them around would be really cool stuff. Maybe now that “cloud” is a buzzword, this could catch on — not only is the processing moving up into the “cloud” but the actual work being done zaps around like lightning bolts.

        lol the problem for me is I don’t have the spare cycles to spend on it. If you make progress, or have more thinking, I’d be interested to see it.

  4. roby2358

    lol actually I think I just re-invented SmallTalk πŸ˜‰

  5. This is an old blog post but if you are still interested in this area, please have look at an architecture we are developing: http://www.slideshare.net/GopiSuvanam/function-augmented-state-transfer-fast-architecture-64151967
    The architecture combines RESTful resource methods and functional programming.
    A detailed paper on the same is here: http://arxiv.org/abs/1607.05075

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s