Skip to content
This repository has been archived by the owner on Jan 10, 2022. It is now read-only.

Core Routing

cliftonc edited this page Jul 29, 2011 · 11 revisions

Routing

Routing in Calipso refers to the process by which Calipso, and all of its enabled modules, respond to a request. The key principle of Calipso is that modules do their work asynchronously, and in parallel, wherever possible to optimise performance and scalability, and routing is a crucial part of this philosophy.

As described in the Core Calipso and Core Calipso Router sections, we can see that at the heart Calipso is just Connect middleware that responds in the normal fashion (req,res,next). Once inside the Calipso Router however the way that specific modules are invoked is different to a typical Express approach (e.g. the modules are not just more Express middleware).

What is a route?

A route in Calipso is two things, the first is a description of a HTTP request that will act as a selector, that when matched will cause the specified function described in the route to be called.

GET /object/:id  => showObjectByID
POST /object/:id => updateObject
/^content.*/     => listContent    

It can be either a string, in the form:

<METHOD> <URL_PATTERN>

Or a regular expression:

<REGEX>

When a Url Pattern is supplied, it may contain selectors that allow parts of the URl to be converted into parameters, this takes the form :variable, for example:

GET /object/:id  => GET /object/123

Will then set the property id to 123, for example, inside a routing function:

req.moduleParams.id = 123 

Additionally, any query string parameters will also be mapped by default, so:

GET /object/:id  => GET /object/123?view=summary

Will result in:

req.moduleParams.id = 123 req.moduleParams.view = 'summary'

First Up - Modules Initialise Their Own Routes in Init

Every module must expose two functions - init and route - the first of these (init) is described externally in the Core Calipso Router pseudo-code, describing how dependent modules are loaded and then initialised based on events.

Inside the init function modules will typically declare the routes that they will respond to. I say typically, as a module may not actually respond to any routes, it may only alter other modules or provide background jobs (feeds is a good example of this).

Within a module initialisation function (which must be function that looks like):

function init(module, app, next) {
   // Initialise the module
   next();
};

Module is an injected reference to the module object that references this module object held in the calipso.modules hashmap (as the functions that the module exports is not the entirety of what Calipso views as a module - see Modules.

Note: The app shortcut is actually unnecessary (it is accessible via calipso.app) and needs to be refactored out.

Lets now provide an example (from the template module):

function init(module, app, next) {
      
  calipso.lib.step(

    function defineRoutes() {
  
      // Add a route to every page, notice the 'end:false' to ensure block further routing
      module.router.addRoute(/.*/, allPages, {            
        template: 'templateAll',
        block: 'right'
      }, this.parallel());
  
      // Page
      module.router.addRoute('GET /template', templatePage, {
        template: 'templateShow',
        block: 'content'
      }, this.parallel());
  
    }, function done() {
  
      // Any further configuration goes here
      next();
  
    }
  );

};

Lets step through this:

  1. The function uses step. This is because the module.router.addRoute function is asynchronous, and we need each of the routes to be registered in parallel, so we use step to control this flow.
  2. Mutiple routes are added, that map to specific module functions, e.g. /.*/ => allPages.
  3. Any final configuration is then done afterwards (though it could equally be done before).

Module Router

When modules are loaded they also have a new instance of the object returned by lib/Router.js attached to them, this is then referred to in the initialisation function as module.router (also accessible via full path @ calipso.modules.moduleName.router).

The module router is an instance of an object that exposes the following properties and functions:

moduleName: moduleName
modulePath: modulePath
addRoute: function(path, fn, options, next)
route: function(req, res, next)
routes: []
Clone this wiki locally