====
Y.mojito.RouteMaker
responsibilities are the following:
- (1) normalize the internal representation of
routes.json
- (2) given a "path", look up the matching path
- (3) given a "query", construct a URI
(2) and (3) will take into parametrized values into consideration.
====
Step 1:
User provide configuration via routes.json
.
[{
"settings": [ "master" ],
"root": {
"path": "/xxx", // the path that will trigger this route
"call": "instance.action", // the mojit instance and action to execute for this route
"verbs": [ "get" ] // array of methods here
}
}]
Step 2:
Mojito normalizes the above data structure into an internal representation.
{
"path": "/:mojitos",
"call": "@Page.index",
"regex": {
"mojitos": "\\d{1,2}_[Mm]ojitos?"
},
"name": "complex",
"verbs": {
"GET": true
},
// NOTE: the definitions of "params" and "query" is slightly skewed in the context
// of routing configuration
//
// "params" property is used to specify parameters to be appended as query string
// to the generated URL as part the route definition.
"params": {
"mojitos": "12_Mojitos"
},
// "query" property is used to group parametrized paths for substitution later
"query": {
"mojitos": "12_Mojitos"
},
// "requires" is used to group all parametrized paths.
// a parametrized path is a name prefixed with a ":", e.g. ":name" , and is a
// placeholder to either:
// (1) invoke a mojit via "call" based on the path, or
// (2) using regex to match a path
//
// "requires" keeps track of all parametrized paths
"requires": {
"mojitos": "\\d{1,2}_[Mm]ojitos?"
},
// "ext_match" is used to path a given path with the "route.path" value
// internally, something like this happens:
// if (new RegExp(route.ext_match).test(path)) { ... }
"ext_match": "^/(\\d{1,2}_[Mm]ojitos?)$",
"int_match": "^mojitos=\\d{1,2}_[Mm]ojitos?$"
}
All lookup operations are done on the internal route configuration.
====
/**
Resolve all "params" that which are defined in "route.requires"
Those resolved parameters are then added to "route.query"
@param {Object} route the route configuration wih the following properties
@param {Object} route.requires
@param {Object} route.query
@param {Object} params a set of parameters with their values to be used
**/
function resolveParams(route, params)
====
- invoked on
find()
given a path - based on a path, a parametrized route.path, replace the parametrized
route.call
to match the path.
// route config
{
path: "/root/:value",
call: "page.{value}"
}
Given path=/root/foo
, the route.call
will be substituted with page.foo
.
====
/**
@param {String} path e.g. '/foo/bar'
@param {String} verb e.g. 'GET'
@return {Object} the route configuration object, with values replaced as required
**/
find(uri, verb)
Given a path
:
- iterate through the routes configuration and return the first matching one
- substitute any parametrized
route.call
based on theroute.path
and the givenpath
- any parametrized
route.path
that is not declared inroute.call
are added toroute.params
- adds the extracted URI parametrized paths to the
route.query
object (NOTE: a bit of duplication here , since that was already done bydoCallReplacement
) - add any original
route.params
that was defined in the route configuration toroute.query
if they are not already set
====
/**
@param {String} query e.g. 'foo.bar'
@param {String} verb e.g. 'GET'
@param {Object} params extra query string to tag onto the returned URI. "query" querystring will take priority over "params"
@return {String} the URI matching the query
**/
make(query, verb, params)
e.g.
make('foo.bar', 'GET', {foo: 'bar'})
make('foo.bar?foo=bar', 'GET', {});
Given a query
:
- if the
query
has a querystring portion, it replaces the givenparams
- matches the
query
from the routes configuration based on the following criteria:- is the call an exact match ? (as in
if (call === route.call && route.verbs[verb]) { ... }
) - is it a wild card match ?
- if so, set
route.params.module = callId; route.params.action = callAction;
- resolve the parametrized paths based on the
route.call
value based onroute.requires
- if so, set
- otherwise, try to match the route based on "wild cards"
- is the call an exact match ? (as in