Aprendiendo NodeJS

2016-01-03

Estas últimas semanas algunos compañeros de Software Craftsmanship GC hemos estado aprendiendo NodeJS. Yo he estado siguiendo el curso de pluralsight: Building Web Applications with Node.js and Express 4.0. Además como proyecto de aprendizaje para aplicar lo aprendido estamos haciendo un blog. Este es el repositorio. A pesar de que el título sea Aprendiendo NodeJS en realidad estamos aprendiendo varias tecnologías al mismo tiempo como Express, EcmaScript 6, mongodb… Por lo tanto, en este post también hablaré de algunas de estas (más concretamente de Express).

Por un lado está lo básico de NodeJS que muchos ya conocíamos de antes. Npm es el node package manager con el cuál gestionamos las dependencias. En un proyecto tenemos un package.json el cual contiene información relevante del proyecto entre la que se encuentra las dependencias del proyecto. Si queremos instalar una dependencia en el proyecto haríamos: npm install –save package-name. Con la opción “–save” hacemos que se guarde en el package.json como dependencia. También tenemos la opción –save-dev con el cuál puedes añadir dependencias de desarrollo. Por último cuando trabajas desde otro ordenador, te vale con hacer un npm install para instalar todas las dependencias recogidas en el package.json y comenzar a trabajar. Una vez instalemos las dependencias, tendremos en la raíz del proyecto una carpeta “node_modules” donde estarán las dependencias que tenemos.

Luego tenemos los módulos de Node. A mí, que vengo del mundo C#/Java, me gusta verlo namespaces/paquetes, no sé si es el símil más correcto pero a mí me ayuda. Gracias a los módulos conseguimos privacidad en JavaScript de manera muy sencilla (ahora con EcmaScript 6 también lo es). Con este ejemplo se ve claramente cómo funciona:

1
2
3
4
5
6
7
8
9
10
// my-module.js
var message = "Hello World!"
function printMessage() {
return message;
}
module.exports = printMessage;
// file where I will use my module
var printMessage = require("./my-module");
printMessage(); // output: Hello World!

Respecto a los módulos, cabe destacar que los módulos que tenemos instalados como dependencias gestionadas a través de npm, también debemos importarlos con el require. En el caso de estos, se podrá obviar la ruta en la que esté el modulo, podremos hacer directamente require(“module”). Sin embargo, los módulos que desarrollemos en el proyecto requerirán la ruta del fichero.

Empecemos con Express. Express es un framework web para NodeJS. A mí personalmente me está gustando por 2 razones principales. La primera, es fácil de usar. La segunda es que, por ahora, nos da la sensación de que desacoplarte del framework es sencillo. Considero que te da bastante libertad para que uses solo aquello que quieres. En nuestro proyecto por ahora tenemos claro que lo usaremos tan solo para las rutas y la autentificación.

El ejemplo más sencillo de una petición get podría ser el siguiente:

1
2
3
4
var express = require("express");
var app = express();
app.get('/hello', (req, res) => res.send('Hello World!'));

Para un controller muy sencillito esto está genial. No obstante, cuando el controller empieza a crecer conviene tener esta parte muy bien modulada. Siguiendo la fórmula anterior, solo haría que nuestro controlador pase a ocupar muchas líneas y sea difícil de seguir. Para esto Express nos ofrece los Routers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// app.js
var userRouter = require('./routes/user-router');
app.use("/user", userRouter());
// user-router.js
var userRouter = require('express').Router();
module.exports = function () {
userRouter.route('/contacts')
.get((req, res) => {
// do something
});
return userRouter;
}

Con este ejemplo estaríamos definiendo que nuestro userRouter es el encargado de gestionar las peticiones a la ruta “/user”. Si entramos en el router, este define una nueva ruta que será concatenada a la anterior (“/user/contacts”). Al igual que hemos llamado al get() podemos llamar a otros métodos http además de concatenarlos gracias a una agradable fluent api. Por último, recordar dos cosas:

  • El método all() para una ruta recibe una función asíncrona para un (request y response) independientemente del método http. Esta función se ejecutará siempre antes que el método de la petición.
  • Este método all() tiene un equivalente a nivel de router. Vendría a ser lo mismo pero para todas las rutas gestionadas por el router en vez de ser para una concreta. El método a usar sería router.use().
    Conclusión

Estamos aprendiendo un montón haciendo sesiones de Mob Programming. Creo que es una muy buena forma de aprender tecnologías cuando existe un interés tan generalizado como en nuestro caso. Estas 2 últimas semanas hemos aprendido mucho más pero no quiero hacer este post muy extenso. Trataré de escribir más sobre Express, mongodb y EcmaScript 6.