[plt-scheme] Implementing web services

From: Anton van Straaten (anton at appsolutions.com)
Date: Tue Aug 14 03:15:04 EDT 2007

John Clements wrote:
> Someone tell me I'm mistaken: it appears to me that REST is simply  
> continuation-based web programming with the additional restriction  that 
> there be only a finite set of possible continuations; the  easiest way 
> to achieve this is to allow only tail calls.  So in  principle, cps-ing 
> achieves REST.  In common use, however,  maintaining a continuation as a 
> POST-style argument is un-idiomatic,  slow, and insecure, so you need to 
> severely restrict the possible  size of the continuation argument.
> 
> Is that a fair summary? Did I just recapitulate the slides I skimmed?

I'd say that's correct as far as it goes (in principle), but there's 
more to it than just restricting the possible size of the continuation 
argument.  The ideal goal (often not achieved) for a REST app is to 
structure it so that continuations can be represented as nothing more 
than URLs which don't depend on any session-specific state.

If you can email a URI to your friend and have it work for her, and if 
it continues to work in the future, then that's a pretty RESTful URI. 
If you take that ability as a goal throughout an application, it implies 
all sorts of things about the structure of the application and its 
continuations.

Some of those things are probably what Shriram was thinking of when he 
wrote "incredibly hard to implement in practice if you really want to be 
true to Fielding's criteria."

I'm not sure I'd agree about "incredibly hard", unless writing in 
inverted-control style counts, or fighting with frameworks that aren't 
designed to support REST.  But it's not that hard if you design the 
application to fit REST guidelines.  There can be benefits to doing 
that.  It does tend to involve more work, though.

A problem with automatically-generated continuations, as in send/suspend 
etc., is that it can be difficult to limit them to just the relevant 
state.  They're also not intended to be persistent.

To use a simple concrete example, say we extend the "add.ss" example 
servlet to maintain a running total of the numbers that have been 
entered so far.  I then patiently sit at my browser and add up a few 
hundred numbers.  Now I want to bookmark one of the result pages, or add 
its URI to a wiki, or email the URI to a colleague.

With a continuation-based server, one runs into a slew of issues at this 
point:

* The dependency on a POST request prevents its use in this way.  POST 
requests are OK for submitting data, but in REST terms the resulting 
page should be identified only by its URI.  You can of course address 
this with the post-redirect-get pattern.  This can of course be done 
easily enough, but it points out one way in which applications have to 
be structured to support REST.

* The continuation (and its URI) isn't persistent - e.g. it can time 
out, and it doesn't survive server restarts.  This is a big one which 
effectively eliminates non-persistent continuations as a candidate for 
development of REST apps.

* In a slightly more sophisticated application which supports user 
logins, an identifier for the logged-in user would typically end up 
being stored in the continuation, unless you take active steps to 
prevent it.  That information, along with various other kinds of 
session-related info, is orthogonal to the resource being referenced by 
a URI, and you don't want the URI to somehow "contain" this information 
and thus either limit its usefulness, or even compromise security.

* etc.

If you think of REST as identifying a set of tradeoffs (at least, 
Fielding's paper does that), and giving a name to a region in that 
tradeoff space, then continuation-based servers as currently conceived 
tend to overlap the edges of that space, at best.  Although in 
principle, the CPS+lambda-lifting+defunctionalization transformation 
gets you to a similarly structured application, that's not enough by itself.

Anton


Posted on the users mailing list.