Skip to content

Instantly share code, notes, and snippets.

@imalberto
Last active December 19, 2015 19:18
Show Gist options
  • Save imalberto/6004769 to your computer and use it in GitHub Desktop.
Save imalberto/6004769 to your computer and use it in GitHub Desktop.
mojito-router-annotated

the why

====

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.

mojito router config

====

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.

resolveParams

====

/**
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)

doCallReplacement

====

  • 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.

find()

====

/**
@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 the route.path and the given path
  • any parametrized route.path that is not declared in route.call are added to route.params
  • adds the extracted URI parametrized paths to the route.query object (NOTE: a bit of duplication here , since that was already done by doCallReplacement)
  • add any original route.params that was defined in the route configuration to route.query if they are not already set

make()

====

/**
@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 given params
  • 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 on route.requires
    • otherwise, try to match the route based on "wild cards"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment