Skip to content

Static URL Routing

October 4, 2010

This is the third in a series of articles about web programming in Dylan. This example will show how URL routing works in the Dylan web server, and how to handle optional URL elements for your resources.

I will skip the library and module definitions since they’re essentially the same as in the previous examples, but they are included in the full code listing at the end.

In the Dylan web server, add-resource maps a URL to a resource. The default implementation of add-resource builds up a tree structure whose paths are defined by URL path elements and whose leaves are <resource> objects. (Idea stolen from twisted.web. I hope to add a simple regular expression based router in the future, for comparison.)

For this example we’ll use a hypothetical wiki as our web application and add three different URLs for it. First, we need a $wiki-app resource that will be the root of all wiki URLs, and specialized resource classes to provide behavior. We’ll implement page, user and group resources for the wiki:

 
define constant $wiki-app = make(<resource>);
define class <page> (<resource>) end;
define class <user> (<resource>) end;
define class <group> (<resource>) end;

Now wiki resources can be added as children of $wiki-app:

 
add-resource($wiki-app, "page/{action}/{title}/{version?}", make(<page>));
add-resource($wiki-app, "user/{action}/{name}", make(<user>));
add-resource($wiki-app, "group/{action}/{name}", make(<group>))

The URL path elements surrounded by curly braces are "path variables". Let’s decompose the first URL above: page/{action}/{title}/{version?}. The first element, "page" must be matched literally. The {action} and {title} elements are required path variables; if either is missing 404 is returned. The last element, {version?} is optional, as indicated by the ‘?’ character. (Two more path variable types that aren’t shown here are available: {v*} matches zero or more path elements and {v+} matches one or more.)

In order to define the behavior of our various resources we define methods on the respond generic function. Note that each path variable in the URL passed to add-resource corresponds to a keyword in the respond method for the resource being added. (For our purposes the behavior will be to simply display the values of all the path variables.)

 
define method respond
    (resource :: <page>, #key action, title, version)
  output("<html><body>action = %s, title = %s, version = %s</body></html>",
         action, title, version);
end;

The respond methods for <user> and <group> are similar. Notice that version may be #f but action and title will always be strings.

Lastly, we’ll connect $wiki-app to the root URL (/) and start the server:

 
define constant $server = make(<http-server>, listeners: #("0.0.0.0:8888"));
add-resource($server, "/", $wiki-app);
start-server($server);

That’s it. Run the server and click on some of these URLs to see the corresponding behavior:

Here’s the full code listing:

 
-----------library.dylan------------
Module: dylan-user
 
define library web60-static-routing
  use common-dylan;
  use koala;
end;
 
define module web60-static-routing
  use common-dylan;
  use koala;
end;
 
-----------static-routing.dylan------------
Module: web60-static-routing
 
define constant $wiki-app = make(<resource>);
 
define class <page> (<resource>) end;
define class <user> (<resource>) end;
define class <group> (<resource>) end;
 
add-resource($wiki-app, "page/{action}/{title}/{version?}", make(<page>));
add-resource($wiki-app, "user/{action}/{name}", make(<user>));
add-resource($wiki-app, "group/{action}/{name}", make(<group>));
 
define method respond
    (resource :: <page>, #key action, title, version)
  output("<html><body>action = %s, title = %s, version = %s</body></html>",
         action, title, version);
end;
 
define method respond
    (resource :: type-union(<user>, <group>), #key action, name)
  output("<html><body>action = %s, name = %s</body></html>",
         action, name);
end;
 
define constant $server = make(<http-server>, listeners: #("0.0.0.0:8888"));
add-resource($server, "/", $wiki-app);
start-server($server);

Previous: Serving Dynamic Content

Back to top

Advertisements

From → Computers, Dylan

One Comment

Trackbacks & Pingbacks

  1. Dylan Web in 60 Seconds « cgay's random notes

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

%d bloggers like this: