Node, JavaScript, and supporting REST code-on-demand in Web API

Topics: Web Api
Jan 8, 2012 at 5:03 PM

The REST architectural style has a 'Code on Demand' optional constraint.

See here in Fielding's thesis, also here.  Also see this observation from Joe Gregorio.

Excerpt: "In the code-on-demand style, a client component has access to a set of resources, but not the know-how on how to process them. It sends a request to a remote server for the code representing that know-how, receives that code, and executes it locally." (Roy Fielding)

Let us consider a REST service that exposes resource representations in JSON, based on one or more private media types; i.e. media types that are introduced by that service.  The Sun Cloud API is a good example of this.  But it could just as well be your REST service, and mine too.  Clients have access to a set of resources, and they do have the know-how to process them, because the media types are all (hopefully) well documented.

However, for any one REST service, there are N clients of that service.  The service provider hopes for a high N value, as high as possible.  But as N increases, so too does the chance of a client misinterpreting the semantics of a media type.  The chance increases (e.g.) that a client will hardcode a server-generated URI that should not be hardcoded.  Plus if all those N clients have to separately interpret and parse and correctly interoperate with each media type - that's a lot of duplicated work.

What if the service did that work?  What if the service were to write a code-on-demand, per-media type, downloadable script - available to any/all clients - that correctly interpreted resource respresentations based on that media type?  The script would does its work in the service-approved way.  Plus it would evolve as the schema for the media type's JSON evolved over time (hopefully maintaining backward compatibility).  This takes a load of work off all those clients, and helps ensure that clients get implemented correctly.  It reduces the amount of time and brain power that each client implementor would otherwise have to expend parsing each media type's written documentation.

So services supply downloadable scripts to interpret their own media types on the client, but in what language?  Answer: JavaScript.

If Node teaches us anything, it's that JavaScript can be run anywhere.  We all know it runs in the browser.  Node allows it to be run on the server, and also allows it to implement CLI apps.  Mike Amundsen's book has some great examples of this; consider the second of his client-side apps in Chapter 3, which uses JavaScript to write a CLI app to process a specific media type.

Here is Fielding on why JavaScript is a better fit over Java applets (and this was written over 10 years ago).

So... I'll jump to my end conclusion right now: I'd like to see every REST client framework support JavaScript execution, for the above reasons (and there are probably other use cases aside from interpreting media types' resource representations).

But here we're talking about one REST framework: Web API.  So I'd like to see Web API's client-assist classes support JavaScript execution.  It doesn't matter whether it's done via Node, or embedding Google V8 directly, or some other means.

Now I'll give an example of my use case from my own REST service:-  The top-level "Service" resource indicates whether the user in question has or has not accepted the latest EULA. If they have, then the number of (financial) portfolios owned by the user is given. A hypermedia control to the EULA resource is always given. A hypermedia control to the user's collection of portfolios is given, but only if he/she has accepted the EULA.

The above info, plus a link to the client-side "media type processor" script, forms a JSON-based representation of the "Service" resource. The script takes the form of a JavaScript 'class' (for want of a better term) whose ctor function is called "Service". The ctor function takes the complete JSON message body (aka resource representation) as an arg, and initialises itself with that. The ctor function has functions attached to its prototype (i.e. methods) that expose in programmatic terms:

  • gets flag saying whether the user has accepted the EULA or not
  • gets the total number of portfolios that the user owns (returns null if user hasn't accepted EULA)
  • gets URI of the EULA resource
  • gets URI of the portfolios collection resource (returns null if user hasn't accepted EULA)

One final thing: even if a REST client wasn't able to execute a c-o-d "media type processor" script, it would still be wise for the REST service implementor to write such a script, and make it available as an intrinsic part of a media type's documentation.  I.e. it would provide a reference implementation that client authors could translate into their own terms: C#, VB, Java, Ruby, whatever.