I sort of stumbled on this idea while playing around with Rails-style filters. But this might be a good solution for routing web requests:
class Weblet
{
**
** Route this request to another Weblet, returning the instance of
** the Weblet to route request to. Return null from this method to
** send a 404 Not Found response. The default implementation
** returns this.
**
virtual Weblet route(WebReq req, WebRes res)
{
return this
}
}
So web requests essentially get routed down similar to a tree. The root Weblet for fandev.org might look like this:
class Root extends Weblet
{
override Weblet route(WebReq req, WebRes res)
{
if (req.uri == "/") return Home.make
if (req.uri.startsWith("/discussion")) return Discussion.make
return null
}
}
And the Discussion weblet would further route based on your URL.
andyTue 27 Jun 2006
I've struggled with coming up with a good design for URL-Weblet mapping. The goal of course is that I want to be able to write all weblets "relatively", so that I can reference URLs in my code as "/foo" when in deployment they may actually be "/a/b/c/foo".
In order to acheive this I need a mechanism to crawl down a set of Weblets from a URL, and also to know my "depth" so I can assemble back a functional URL.
Originally I had thought it would be really easy to do that using a Map and building a Weblet tree:
class Root
{
Void init()
{
add("foo", Foo.make)
}
}
class Foo
{
Void init()
{
add("bar", Bar.make)
}
}
/foo/bar -> Root.get("foo").get("bar") -> Bar
Which makes for a very elegant design, however, it does not address dynamic URLs - like the URL for this page. I can't map 258 straight to a Weblet instance.
So I went back to the route() method, and thought it might be on the right track. But I think instead of working off the URI directly, WebReq includes another field called path of type Str[], which is just req.uri.split("/").
req.uri -> "/foo/bar"
req.path -> ["foo", "bar"]
And as I walk down my tree using route(), I can clip off the starting path:
class Root
{
Weblet route(WebReq req, WebRes res)
{
// Where req.clip -> ["foo", "bar"] -> ["bar"]
if (req.path.first == "foo")
return Foo.make.route(req.clip, res)
return this
}
}
class Foo
{
Weblet route(WebReq req, WebRes res)
{
if (req.path.first == "bar") return Bar.make
return this
}
}
The issue here is that I am creating a new instance of every Weblet on the way down - maybe that method is static - I don't know. But then you can get your real URL using your current path:
Where that code is probably a convenience method on WebReq. Or acutally, probably more efficient is that every time you clip(), I append that to a contextPath field on WebReq:
andy Wed 14 Jun 2006
I sort of stumbled on this idea while playing around with Rails-style filters. But this might be a good solution for routing web requests:
So web requests essentially get routed down similar to a tree. The root Weblet for fandev.org might look like this:
And the Discussion weblet would further route based on your URL.
andy Tue 27 Jun 2006
I've struggled with coming up with a good design for URL-Weblet mapping. The goal of course is that I want to be able to write all weblets "relatively", so that I can reference URLs in my code as "/foo" when in deployment they may actually be "/a/b/c/foo".
In order to acheive this I need a mechanism to crawl down a set of Weblets from a URL, and also to know my "depth" so I can assemble back a functional URL.
Originally I had thought it would be really easy to do that using a Map and building a Weblet tree:
Which makes for a very elegant design, however, it does not address dynamic URLs - like the URL for this page. I can't map 258 straight to a Weblet instance.
So I went back to the route() method, and thought it might be on the right track. But I think instead of working off the URI directly, WebReq includes another field called path of type Str[], which is just req.uri.split("/").
And as I walk down my tree using route(), I can clip off the starting path:
The issue here is that I am creating a new instance of every Weblet on the way down - maybe that method is static - I don't know. But then you can get your real URL using your current path:
Where that code is probably a convenience method on WebReq. Or acutally, probably more efficient is that every time you clip(), I append that to a contextPath field on WebReq: