Nodejs + Express + MongoDB

Introducción

Típica three-tier-architecture:

  • Client
  • Application
  • Database

Basado en esto.

Instalaciones

Para ello, en el directorio donde va a residir nuestra aplicación:

$ npm install express

(o npm install -g express si queremos que se instale globalemente)

Creamos un proyecto. Como yo lo he hecho localmente:

$ ./node_modules/express/bin/express --sessions nodetest1

Modificamos nodetest1/package.json

Este paquete controla las dependencias, la versión de la aplicación, ...:

 {
    "name": "application-name",
    "version": "0.0.1",
    "private": true,
    "scripts": {
        "start": "node app.js"
    },
    "dependencies": {
        "express": "3.4.4",
        "jade": "*"
    }
}

Las dependencias se instalan mediante:

$ cd nodetest1 && npm install

Si instalamos “express” localmente, ahora volverá a instalarlo dentro de nodetest1 y si lo teníamos instalado globalmente, no será necesario.

Podemos ejecutar la aplicación mediante:

$ node app

y mostrará:

Express

Welcome to Express

Es bueno curiosear el contenido del fichero app.js. En ésta web se explica.

Nuestra web

Si añadimos en app.js lo siguiente:

app.get('/helloworld', routes.helloworld);

y reiniciamos el servidor, nos dará un error porque no hemos modificado la ruta para que maneja la request.

Para ello, añadimos en routes/index.js:

exports.helloworld = function(req, res){
   res.render('helloworld', { title: 'Hello, World!' });
};

y creamos el template al que estamos llamando views/helloworld.jade:

extends layout

block content
   h1= title
   p Welcome to #{title}

Instalamos MongoDB

Para ello:

yaourt -S mongodb

ocupa 180Mbytes instalado. ¡Ojo! La versión de 32bits está limitada a unos 2Gbytes de datos.

Creamos la base de datos de nuestra aplicación en uno de los directorios:

$ mkdir data
$ mongod --dbpath ./data
[...]
[initandlisten] waiting for connections on port 27017
[...]

Nota

Usaríamos lo típico de “systemctl start mongodb” y luego enable si quisiéramos que funcionase todo el rato.

Mientras, en otro shell creamos nuestra base de datos:

$ use nodetest1
> db.usercollection.insert({ "username" : "testuser1", "email" : "testuser1@testdomain.com" })
> db.usercollection.find().pretty()
{
   "_id" : ObjectId("5335e58e9d20312c8ea80d75"),
   "username" : "testuser1",
   "email" : "testuser1@testdomain.com"
}

Nota

interesa curiosear “mongoDB schema design”.

Añadimos más:

> newstuff = [{ "username" : "testuser2", "email" : "testuser2@testdomain.com" }, { "username" : "testuser3", "email" : "testuser3@testdomain.com" }]
> db.usercollection.insert(newstuff);

Página web que muestra los datos

Queremos que la web muestre lo siguiente:

<ul>
   <li><a href="mailto:testuser1@testdomain.com">testuser1</a></li>
   <li><a href="mailto:testuser2@testdomain.com">testuser2</a></li>
   <li><a href="mailto:testuser3@testdomain.com">testuser3</a></li>
</ul>

y para ello necesitaremos un template que tendrá la siguiente pinta:

extends layout

block content
   h1.
      User List
   ul
      each user, i in userlist
         li
             a(href="mailto:#{user.email}")= user.username

El template lo guardamos en views/userlist.jade.

Por último generamos, la conexión a la base de datos y routing.

Modificamos app.js para conectar con la base de datos:

// New Code
var mongo = require('mongo');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1');

añadiéndolo justo después del resto de “require”.

Obviamente esto requiere modificar package.json:

"dependencies": {
       "express": "3.4.4",
       "jade": "*",
       "mongo":"*",
       "monk":"*"
   }

y ejecutar de nuevo:

$ npm install

para que se instalen los modulos “mongo” y “monk”.

Añadimos el routing a app.js:

app.get('/userlist', routes.userlist(db));

en donde vemos que pasamos la base de datos como parámetro.

Creamos la ruta en index.js:

exports.userlist = function(db) {
  return function(req, res) {
      var collection = db.get('usercollection');
      collection.find({},{},function(e,docs){
          res.render('userlist', {
              "userlist" : docs
          });
      });
  };
};

Añadir datos a la base de datos

Asociamos la ruta “newuser” en app.js:

app.get('/newuser', routes.newuser);

y creamos la ruta en index.js:

exports.newuser = function(req, res){
  res.render('newuser', { title: 'Add New User' });
};

Finalmente creamos el template para “newuser”:

extends layout

block content
   h1= title
   form#formAddUser(name="adduser",method="post",action="/adduser")
      input#inputUserName(type="text", placeholder="username", name="username")
      input#inputUserEmail(type="text", placeholder="useremail", name="useremail")
      button#btnSubmit(type="submit") submit

que como vemos, una vez presionamos “submit” aplica el métido “post” en la ruta “adduser”.

Finalmente, creamos la ruta que recibirá los datos del formulario. Para ello, modificamos app.js:

app.post('/adduser', routes.adduser(db));

y en index.js creamos la lógica:

exports.adduser = function(db) {
 return function(req, res) {

     // Get our form values. These rely on the "name" attributes
     var userName = req.body.username;
     var userEmail = req.body.useremail;

     // Set our collection
     var collection = db.get('usercollection');

     // Submit to the DB
     collection.insert({
         "username" : userName,
         "email" : userEmail
     }, function (err, doc) {
         if (err) {
             // If it failed, return error
             res.send("There was a problem adding the information to the database.");
         }
         else {
             // If it worked, set the header so the address bar doesn't still say /adduser
             res.location("userlist");
             // And forward to success page
             res.redirect("userlist");
         }
     });

  }
}

Seguir probando con un ejemplo RESTFUL: http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/