Integrando MongoDB

02/11/2016 MongoDB

Introducción

MongoDB es una de las BBDD NoSQL más populares. Integrarla en Express es tremendamente sencillo gracias al ORM Mongoose.

Setup

Lo primero que deberemos hacer es instalar este Motor de Base de datos en nuestro PC. Deberemos descargarlo e instalarlo. Comprobaremos que se ha instalado correctamente si en una consola escribimos mongo --version y nos devuelve un número de versión.

Nota: Si el sistema indica que no existe el comando, es por que no estará configurado en las Variables de Entorno del Sistema. Deberemos añadir Mongo al Path. Por ejemplo, en Windows podría ser una ruta como C:\Program Files\MongoDB\Server\3.2\bin.

Podemos lanzar el cliente de Mongo con mongod, sin embargo, saltará un error al no haber sido configurado previamente.

Configuración

MongoDB requiere de un directorio donde guardar sus archivos, por defecto los buscará en C:\data\db (Windows) ó /data/db (Linux). Esos directorios no existirán a menos que los creemos. Tenemos dos opciones:

  1. Crearlo, simplemente se tratará de crear esas dos carpetas en esa ruta.
  2. Crearlos en cualquier otra ruta. Al ser otra ruta distinta a la por defecto, deberemos indicarle a Mongo cuál es esa nueva ruta cada vez que lancemos el cliente.

Para lanzar el cliente de Mongo indicando la ruta, lo hacemos así:

mongod --dbpath="ruta\data\db"

Si todo va bien, tendremos una instancia de Mongo en ejecución en nuestro PC.

Mongo Client

Ahora, nuestro Servidor de MongoDB estará escuchando atento ante cualquier conexión de un Cliente.

Variables de Entorno

Es buena práctica centralizar las Variables de Entorno de la Aplicación en un archivo .env. En este archivo ubicaremos algunas variables sensibles, entre ellas, la Uri de nuestra BBDD.

Para hacer uso del archivo .env podemos usar el paquete dotenv. Escribimos en la consola:

npm install -S dotenv

El archivo .env

En la raíz de nuestro proyecto, tendremos nuestro .env, lo editaremos para que contenga la siguiente información:

                DB_HOST="mongodb://localhost/expressDev"
                MONGO_DATA_PATH="C:\Program Files\MongoDB\data\db"
                NODE_ENV=local
                DB_USER=
                DB_PASS=
                PORT=
            

La variable más importante será la de DB_HOST. Deberemos indicar el nombre que queremos que tenga nuestra BBDD con mongodb://localhost/[nombre].

En la variable MONGO_DATA_PATH pondremos la ruta donde hemos creado los directorios de datos.

Ahora modificaremos el archivo bin/www para que haga uso del archivo .env. Al comienzo de todo el archivo, escribiremos:

                
                    /**
                     * Module dependencies.
                     */
                    require('dotenv').config();
                
            

Con esto, en cualquier parte del código del Back-End, podremos acceder a cualquier variable del .env mediante:

                
                    var variable = process.env.Variable
                
            

Recordemos que el archivo .env no debe compartirse ya que es único de cada entorno.

Mongoose

Con MongoDB instalado en el sistema, podemos proceder a hacer que Express haga uso de él. Lo haremos usando Mongoose. Para ello, lo instalaremos con:

npm install -S mongoose

Integrando Mongoose en Express

Para realizar la integración correctamente, deberemos crear alguno archivos.

  1. Un directorio models dentro de server
  2. Dentro de models crearemos un archivo db.js

En el archivo db.js escribiremos:

                
                    const mongoose = require('mongoose');
                    const readLine = require('readline');
                    var dbURI = process.env.DB_HOST;
                    var gracefulShutdown;

                    if (process.env.NODE_ENV === 'production') {
                        dbURI = process.env.MONGOLAB_URI; // para cuando este subido a producción
                    }

                    // Make the connection
                    mongoose.connect(dbURI, (err, res) => {;
                        if (err) {
                            console.log('ERROR: connecting to Database. ' + err);
                        }
                    });

                    mongoose.connection.on('connected', () => {
                        console.log('Mongoose connected to ' + dbURI);
                    });

                    mongoose.connection.on('error', (err) => {
                        console.log('Mongoose connection error: ' + err);
                    });

                    mongoose.connection.on('disconnected', () => {
                        console.log('Mongoose disconnected');
                    });

                    gracefulShutdown = function (msg, callback) {
                        mongoose.connection.close( () =>{
                            console.log('Mongoose disconnected through ' + msg);
                            callback();
                        });
                    };

                    if (process.platform === 'win32') {
                        var rl = readLine.createInterface({
                            input: process.stdin,
                            output: process.stdout
                        });
                        rl.on('SIGINT', () => {
                            process.emit('SIGINT');
                        });
                        rl.on('SIGUSR2', () => {
                            process.emit('SIGUSR2');
                        });
                        rl.on('SIGTERM', () => {
                            process.emit('SIGTERM');
                        });
                    }

                    //For Nodemon restarts
                    process.once('SIGUSR2', function () {
                        gracefulShutdown('nodemon restart', function () {
                            process.kill(process.pid, 'SIGUSR2');
                        });
                    });
                    //For app
                    process.on('SIGINT', function () {
                        gracefulShutdown('app termination', function () {
                            process.exit(0);
                        });
                    });
                    //For Heroku app
                    process.on('SIGTERM', function () {
                        gracefulShutdown('Heroku app shutdown', function () {
                            process.exit(0);
                        });
                    });
                
            

Lo más importante aqui es la línea 11, donde hacemos la conexión a MongoDB mediante mongoose.connect(uri).

Integrando Mongoose en Express

Ahora modificaremos el archivo app.js para que haga uso del modelo que acabamos de crear:

                
                    ...
                    var bodyParser = require('body-parser');

                    require('./server/models/db.js');

                    var index = require('./routes/index');
                    ...
                
            

Ahora guardamos todo, nos aseguramos de que tenemos una instancia de Mongo en ejecución y lanzamos gulp nodemon. Deberíamos ver que la aplicación se ejecuta como antes pero esta vez conectándose con MongoDB.

Mongo Client

Listo! Ya tenemos a MongoDB perfectamente integrada en nuestra Aplicación. Usando Mongoose podremos hacer más adelante las típicas operaciones de BBDD como guardar registros, consultar, borrar, etc.

Podeís echarle un vistazo al código aquí.

Si tienes alguna duda o sugerencia, no dudes en participar!