[plt-scheme] Are web-server continuations "safe"?
I've had a number of requests to talk about the bookmarkable URL
package on-list. The library, which is currently unnamed, is basically
the "dispatcher" and "request pipeline" parts from Noel's ICFP 2007
paper:
http://www.untyped.com/downloads/icfp068-welsh.pdf
Here's a little more detail. I shall refer to the nameless library as
"Dispatch" for the purposes of this email. Dispatch has three main
functions:
The first function is to provide a mapping from bookmarkable URLs to
"controller" procedures that handle requests.
Suppose I have a blog. Two things people like to do with blogs are:
view a list of posts and view a single post. I want to create
bookmarkable URLs for these things. In a Ruby-on-Rails aesthetic these
would be something like:
http://www.example.com/ for the index
http://www.example.com/posts/slug for the post
For convenience I want to write separate procedures to handle requests
to these URLs:
list-posts : request -> response
review-post : request string -> response
(the string is the post slug).
Dispatch provides a really quick way to set up mappings from URLs to
controllers. First I write a "site" declaration in a module called
site.ss:
#lang scheme/base
(define-site blog
([(url "/") list-posts]
[(url "/posts/" (string-arg)) review-post]))
then I write my controllers in, say, controller.ss:
#lang scheme/base
(require (file "site.ss"))
(define-controller (list-posts request)
...)
(define-controller (review-posts request slug)
...)
Finally, I write my servlet and use a procedure to dispatch the
request to the relevant controller:
#lang scheme/base
(require (file "site.ss")
(file "controller.ss"))
(define (start initial-request)
(dispatch initial-request blog))
The dispatch function runs through the URL rules in the site until it
finds one that matches the request. Once it's there it calls the
controller.
The second function of Dispatch is to provide a reverse mapping from
controllers to URLs:
One of the beauties of continuation-oriented web programming is that
you don't have to worry about URL structures. I want the same solution
for my permanent bookmarkable URLs. Dispatch provides a procedure,
controller-url, that generates a URL from a controller and a list of
arguments:
controller-url : controller any ... -> string
(controller-url review-post "hello-world") -> "/posts/hello-world"
You don't get the flexibility of state-passing that you get with
continuations, but you do get a nice, friendly, bookmarkable URL.
The third function of Dispatch is to get around an irritating problem
I've had in the past:
I like writing web apps in MVC style. I typically divide my apps into
three sets of modules: one set for the model, one set for the view,
and one set for the controllers. The model is usually a separate
entity, but the view and the controller tend to refer to one another a
lot. I get fed up chasing cyclic require bugs very quickly.
Some people might rightly say "use units", but I find units to be
quite complicated for this kind of thing. They require the creation of
extra signatures that muddy the waters a little, and they don't
integrate properly with DrScheme's "Check Syntax" view, which I tend
to use heavily.
Dispatch solves this problem with a quick and dirty bit of mutation.
All the actual definitions are provided by define-site in site.ss: the
define-controller macro simply updates the relevant definition with
the body procedure. You can require "site.ss" all over your software
and call any controller directly, by continuation or via controller-url.
There are another couple of features too. Ones that spring to mind:
- the arguments in URLs can generate controller arguments of arbitrary
types;
- and there's built-in support for the "request pipelines" described
in the ICFP paper.
Anyway, Dispatch is pretty much ready for release. I really just need
a witty name and a little more documentation. I'm going to have a few
hours on the train over the next couple of days so hopefully I'll make
some headway and get it out this week.
Cheers,
-- Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20080304/9c137172/attachment.html>