Enrutado Pillars.js Reference

Source

Sumario

Para crear el enrutado en la aplicación, se añaden al proyecto en la propiedad project.routes, objetos route.

project.routes.add(
  new Route( configuration, handler );
);

Se pueden instanciar y añadir tantos objetos route como sea necesario.

Características del enrutado:

  • Es dinámico, es posible modificar los valores de las propiedades de los objetos en caliente, por lo que se aplican los cambios en el enrutado ipso-facto.
  • Convención sobre configuración , los objetos route se pueden declarar sin configuración o con una configuración mínima, por lo que tomará los valores predeterminados.
  • Los objetos route son anidables, por lo que permiten organizar y agrupar funcionalidades. En estos casos, el nodo padre será el que se conecte al proyecto, y entrará en juego la herencia de la configuración de los objetos route.

Constructor route

myRoute = new Route( configuration, handler );
  • configuration: Opcional. Conjunto de propiedades del objeto route.
  • handler: Opcional. Manejador que se ejecutará siempre y cuando la petición coincida con la configuración del objeto route. El handler siempre recibe como parámetro el objeto gangway.
var myRoute = new Route({
id:"identificador",
path:"/"
//resto de propiedades si las hubiere
},function(gw){
//acciones
gw.send("Fin de la ejecución del manejador");
});

// Una vez creado el objeto, o en la misma sentencia en la
// que se instancia, se añade al proyecto para que forme parte del enrutado:
project.routes.add(myRoute);

Propiedades de route

Route.prototype.id

String identificador del objeto route. Si no se declara el id en la creación del objeto, se autogenera.

Route.prototype.path

Path al que responderá el controlador. Por defecto es '/'. String.

Están soportadas las rutas parametrizadas por lo que están permitidas las formas path:'/*:var', path:'/:var', etc.

Route.prototype.method

Método de petición que acepta el controlador. Para un sólo método acepta un String, para dos métodos se setea como Array. Por defecto es undefined, caso en el que acepta cualquier método, se puede establecer un método específico, o varios que serán los únicos aceptados. Los métodos del protocolo HTTP son: HEAD, GET, POST, PUT, DELETE, TRACE, OPTIONS y CONNECT.

project.routes.add(new Route({
method: "GET",
path: "/get"
},function(gw){
gw.send("Hola solo acepto solicitudes con el método GET");
}));

project.routes.add(new Route({
method: ["GET","POST"],
path: "/getpost"
},function(gw){
gw.send("Hola acepto solicitudes con el método GET y POST");
}));

La propiedad .method es heredable en una estructura arbórea de objetos route.

Route.prototype.host

Host al que responderá el route. String. Por defecto es undefined, por lo que acepta todos los host.

Route.prototype.https

Propiedad para indicar si el objeto route acepta conexiones http, https o ambas. Por defecto es undefined.

  • undefined para permitir http y https.
  • true para sólo permitir conexiones https.
  • false para sólo permitir conexiones http.

Route.prototype.multipart

Tipo Boolean. true para indicar que el controlador acepte ficheros. Hay que tener en cuenta que la propiedad .method deberá estar seteada en POST para que acepte ficheros.

false para no aceptar ficheros.

Route.prototype.maxUploadSize

Propiedad para modificar el tamaño máximo permitido de solicitud para el route concreto.

Esta propiedad originalmente está definida en project.config.maxUploadSize con el valor por defecto de 5 Megabytes(5*1024*1024)

Si definimos esta propiedad en el objeto route, se aplicará este límite sólo en dicho controlador. Y obviamente, en este controladoar prevalecerá esta configuración que la establecida en el proyecto de forma genérica.

Route.prototype.cors

Boolean, por defecto es false. Es utilizado en el middleware cors, define si otros sitios web van a poder utilizar recursos de este objeto.

  • false indica que no acepta solicitudes cors de ningún origen.
  • true indica que acepta solicitudes cors de cualquier origen.
  • Si se especifica un Array de strings, podemos definir de qué dominios concretos acepta nuestro servidor solicitudes cors.

Route.prototype.session

Es utilizado por el middleware sessions.js para establecer sesiones de usuario. Las sesiones se establecen con persistencia en memoria, por lo que si se apaga el servidor se pierden. (Más adelante se ampliará a sistema de sesiones con persistencia en base de datos)

Boolean, false por defecto. true para activar sesiones.

Route.prototype.routes

Cada objeto route a su vez, posee la propiedad routes de tipo ObjectArray, que podrá contener los nodos route hijos. El funcionamiento es exactamente igual que project.routes.

Route.prototype.handlers

Listado de manejadores de un route. Los usual es que un objeto route tenga un sólo manejador, aunque es posible crearlo con varios manejadores.

//Creación del middleware
var msg = function(gw,next){
gw.data.myData="Hola Mundo!!!";
next();
};

//Creación del route con un middleware
var myRoute = new Route(
{id:"home"},
msg,
function(gw){
gw.send(gw.data.myData);
}
);

project.routes.add(myRoute);

//Imprime: Hola Mundo!!!

Si bien es cierto, que deberemos sopesar la opción de incluir manejadores intermedios de esta forma, o incluir directamente un Middleware.

La propiedad .handlers devuelve un Array con todos los manejadores del route. Podemos realizar modificaciones de la propiedad:

console.log(myRoute.handlers);

/*Imprime:
[ [Function], [Function] ]
*/


myRoute.handlers.shift(); // Eliminamos el primer elemento del Array
console.log(myRoute.handlers);

/*Imprime:
[ [Function] ]
*/


Route.prototype.active

Boolean que define si el route está activo o no. Por defecto es true, activo.

project.routes.add(new Route({
id:"activo-o-no"
},function(gw){
gw.send("Hola estoy activo!");
}));

project.routes.add(new Route({
id:"switch",
path: "/switch"
},function(gw){
var routeFocus = project.routes.get("activo-o-no");
routeFocus.active = !routeFocus.active;
gw.send("Ahora el route 'activo-o-no' está: "+ routeFocus);
}));

El route con id "switch" cambiará activará y desactivará al route con id "activo-o-no".

Handler de route

Debemos tener en cuenta, que para que el manejador de un objeto route entre en acción, deben de coincidir ciertas propiedades de éste con los de la solicitud. Las propiedades que deben coincidir son: .path, .method, .port , .host y .https.

Manipular el enrutado

Por un lado tenemos la modificación en caliente de propiedades, para lo que es una buena opción conocer el identificador del objeto route a modificar:

project.route.add(new Route({
id: "modificator"
},function(gw){
project.routes.get("otro-id").active = false;
}));

Capturándolo mediante el método .get(), se puede modificar cualquier propiedad del objeto route.

Por otro lado, tenemos que la propiedad project.routes es de tipo Object Array, por lo que dispone de métodos para capturar, añadir, eliminar, etc.

Anidamiento

Es posible crear árboles de controladores, que organicen y agrupen funcionalidades de la aplicación. El nodo raíz será el que se conecte a project.routes.

Para ello cada objeto route tiene la propiedad .routes, de tipo Object Array, y que contendrá a los hijos si los hubiere.

var myRoute = new Route({
id: 'management',
path: '/'
});

var myRouteSonOne = new Route({
id: 'students',
path: '/students'
},function(gw){
//...
});

var myRouteSonTwo = new Route({
id: 'teachers',
path: '/teachers'
},function(gw){
//...
});

myRoute.routes.add(myRouteSonOne);
myRoute.routes.add(myRouteSonTwo);

project.routes.add(myRoute);
  • Sistema de enrutado eficiente. Agrupar controladores mediante anidamiento, tiene ventajas de eficiencia. Y es que el sistema, al realizar el enrutado, buscará coincidencias en los nodos añadidos directamente a project.routes, los nodos padre, si no hay coincidencia, pasa al siguiente nodo padre, y si sí la hay, seguirá con los hijos de éste. De esta forma, no tiene que realizar la búsqueda secuencialmente en todos los nodos.
  • Tiempo Real. Los controladores son conectables y desconectables en tiempo real, de forma que no tendremos que detener la aplicación si queremos que una parte no esté activa, por ejemplo.

myRoute.routes.get('management').remove('teachers');
// una opción mucho mejor que eliminarlo es establecer
// su propiedad .active en false
myRoute.routes.get('management').active = false;

Herencia

En las estructuras anidadas debemos tener en cuenta la herencia de las propiedades de los objetos route.

La configuración declarados en un nodo padre, lo heredarán sus descendientes. Si uno de los nodos hijos redefine una propiedad ya definida en un nodo superior, ésta tomará el valor definido en el hijo.

En el caso del ejemplo gráfico, se crean tres objetos route con la siguiente configuración:

  • myRoute: que define id, cors, https, port, method, maxUploadSize y un parámetro nuevo creado por el usuario: userParam.
  • son1: descendiente directo de myRoute, y que redefine la propiedad method y maxUploadSize. Por lo que éste sólo aceptará el método GET, y su tamaño máximo de la solicitud sube a 5MB. El resto de propiedades serán las mismas que las de myRoute, también dispondrá de la propiedad userParam en true.
  • son2: descendiente directo de myRoute y que no redefine ninguna propiedad. Por lo que las propiedades serán las mismas que las de su nodo superior myRoute.

Las propiedades obtenidas por herencia estarán disponibles en gw.routing.inheritance.

var myRoute = new Route({
id: 'idRoute',
cors: false,
https: false,
port: 3006,
method: ['POST', 'GET'],
maxUploadSize: 2*1024*1024,
userParam: true
},function(gw){
gw.json(gw.routing.inheritance);
});

var son1 = new Route({
id: 'son1',
path: '/son1',
method: 'GET',
maxUploadSize: 5*1024*1024
},function(gw){
gw.json(gw.routing.inheritance);
});

var son2 = new Route({
id: 'son2',
path: '/son2'
},function(gw){
gw.json(gw.routing.inheritance);
});


project.routes.add(myRoute);
myRoute.routes.add(son1);
myRoute.routes.add(son2);

// > http://localhost:3006/
{
"active": true,
"port": 3006,
"method": ["POST","GET"],
"https": false,
"cors": false,
"maxUploadSize": 2097152,
"userParam": true
}

// > http://localhost:3006/son1
{
"active": true,
"port": 3006,
"method": ["GET"],
"https": false,
"cors": false,
"maxUploadSize": 5242880,
"userParam": true
}

// > http://localhost:3006/son2
{
"active": true,
"port": 3006,
"method": ["POST","GET"],
"https": false,
"cors": false,
"maxUploadSize": 2097152,
"userParam": true
}
Volver arriba