-
Notifications
You must be signed in to change notification settings - Fork 1
HTTP Routing
A routing rule is consist of at least three components: a HTTP method, a URI template and a name to the function handled a client request. These components are collected into a list, and all these lists are collected as a complete router rules. Here is an example:
((:get "/foobar" com.liutos.paw.controller:foobar)
(:get (:strict "/bytes") com.liutos.paw.controller:bytes)
(:get #/"/post/\\w+" com.liutos.paw.controller:get-by-id))When a request comes, the function ELOQUENT.MVC.ROUTER::GET will be called, search in the routing rules, to find a rule whose method and uri-template both matches the corresponding part of request. Then return the action in this rule, as the final handler for this request.
The second part in router rule, so called uri-template, has not just one form as string. It can be a string or a list whose first element is one of the following keywords:
:normal
:regexp
:strictThe keyword :NORMAL, as the default one, means the path-info from a request matches the uri-template, if they're different only at the last slash character. For example, path-info "/foobar/" matches the uri-template "/foobar" in :NORMAL mode.
The keyword :REGEXP, as its name, means the path-info from a request matches the uri-template when the regular expression from uri-template matches the path-info. For example, uri-template "/post/\w+" can captures "/post/abc" and "/post/def" and many others.
The keyword :STRICT means the uri-template matches a request only when the path-info is the same string as the uri-template. The tail slash is not ignorable in this mode.
In the code above, there's a special notation #/"/post/\w+". Sequence "#/" is a dispatch reader macro. It's equivalent to the form
(:regexp "/post/\\w+")It's useful because regular expressions are used in many cases.
The mechanism of matching path-info and uri-template is customizable. This is handled by the generic function PATH-INFO= exported from package ELOQUENT.MVC.ROUTER. Specilized the first parameter to a (eql :keyword) form, a new mode is created. For example, in the source code of Eloquent-MVC, the :STRICT mode is implemented by the following code:
(defmethod path-info= ((mode (eql :strict)) (path-info string) (uri-template string))
"Return true when PATH-INFO is the same as URI-TEMPLATE."
(string= path-info uri-template))The action can be a symbol denote a function or a list of the following form:
(function-name arg0 arg1 ...)Normally, if the action is just a symbol(a function's name), it will be called by passing one argument, the HTTP request object. If the action is a list form, then all the argN is extracted from URL by parsing a request'a path-info according to uri-template. For example, there's a uri-template as follow
(:template "/post/:id")and the action is
(foobar id)If the path-info of a request object is "/post/abc", then the router system will generate a plist as follow
(:id "abc")At this time, according to the arg0, the symbol ID, in the action form, the dispatcher will passed the value "abc" extracted from the plist above to the action handler. So the action handler just need to accept one parameter, the ID. It's equivalent to the following form:
(foobar "abc")There're some options can be used to customize the form of applying the action's function. They're like keyword arguments(Actully, they are), list as belowed:
If set to logical false(NIL), the incomming HTTP request object would not be passed to the action function. Otherwise, the current request object will be cons into the arguments list, as the first argument, to the action function.
Its value looks like the bindings form of a LET form. In every binding, the first element(CAR) is a variable name, and the second element will be used as the field name to extract value from query string. For example, the following binding will extract value of parameter "url" from query string, as set to keyword argument :URL, passed to the action function
:query-string-bind ((url "url"))- Home
- Getting Started
- Basic Usage
- Advanced Topics
- APIs
- eloquent.mvc.config
- eloquent.mvc.controller