Of URLs and Methods

For a long time now I’ve been hacking around on a web framework I started from scratch (mainly because they’re fun to code), but recently I started from scratch again using all I’d learnt from trying things out in the earlier prototype and what I’d learnt from other frameworks. So suddenly it’s all got a bit serious and I’m slowly coming together with something that’s looking very promising and for which I have big ambitions for.

Yeah, I know what you’re all thinking, but I think I understand the framework “scene” pretty well now and what it takes for a framework to stand out from the crowd. Time will tell 😉

Anyway, today I’m going to show you how the URL to method resolver works and what you can do with it.

First of all a little example:

class MyTestController:

@public
def index(self, a, b, c):

return “I like twigs”

def page1(self, a, b, c=”w00t”):

return “PHIL COLLINS IS GOD” # I actually got an anonymous letter in the post containing a badge with this on it! o_O

OK, pretty basic stuff and you can probably tell already what the URLs are going to look like for such mappings:

www.mysite.co.uk/MyTest/arg_a/arg_b/arg_c/ maps to the index method
www.mysite.co.uk/MyTest/page1/arg_a/arg_b/arg_c/ maps to the page1 method, so does
www.mysite.co.uk/MyTest/page1/arg_a/arg_b/

Joy.

Time for full complexity mode:

class MyTestController:

@public
def index(self, a, b, *varargs):

return “Hi mum!”

@public
def page1(self, a, b, c=”t00t”, *varargs, **kwargs):

return “burzum”

@public
@constraint(‘a’, r’^[a-zA-Z]*$’)
@constraint(‘c’, r'(some|thing|other)’)
def page2(self, a, b, c=”123″, **kwargs):

return ” ”

Look! you can accept variable arguments(an unknown number of) and keyword arguments(key/value pairs); groovy.

and some URL examples for those:
www.mysite.co.uk/MyTest/arg_a/arg_b/on/and/on/with/ariston maps to the index method
www.mysite.co.uk/MyTest/page1/arg_a/arg_b/arg_c/blah/a_key/a_value/another_key/another_value maps to the page1 method

(I’ll come to page2 in just a moment)

Well done if you noticed that for the page1 URL we’ll only ever have 1 or no variable in varargs as we need the unmapped URL parts (i.e not arg_a, b or c) to be a multiple of 2 so that we can satisfy the key/value pair requirement of the **kwargs. So, chances are you probably wont want to use *varargs and **kwargs in the same method.

page2…. I hope the decorator name (the @foo thing) and the regular expressions gave away what’s going on here. You can choose to constrain some of your arguments if you so whish, it’ll save you having to do some input validation at least.

So there you have it, you can use Python to its full extent as you would in any normal method and the framework does the leg work for you. I _am_ aware that using regular expressions to constrain URL mappings is standard stuff for frameworks these days, yet I think my using them in decorators is far nicer then having a separate messy mappings file.

Oh and by the way… using **kwargs effectively allows you to never create a URL containing ?foo=bar&ugly=yes again! I’m not saying something like www.mysite.co.uk/blog/06/01/2006/sessionid/df7d7sa5hf7g/size/100/ makes much sense to the user (maybe it’s less confusing for the average Joe?) but however you design your URLs is _totally_ up to you 🙂

p.s Please don’t kill me for any grammar/spelling mistakes — I’ve literally been looking at code all day long (the C apps at work were coded by the devil himself, I’m positive)

p.p.s b2evo’s tags don't seem to work too great and I'm too tired to play around with it.