domingo, 7 de abril de 2013

Node.js + MongoDB + express, primer contacto

Desde hace ya bastante tiempo me ronda la cabeza la idea de pasar KomanderTPV a la combinación node.js + mongodb + express.

Actualmente, KomanderTPV corre bajo un Apache y PHP atacando un MySQL. Esta configuración ha sido más que suficiente para los proyectos que he estado realizando hasta el momento.

Pero node + mongoDB resulta bastante más que una mejora en el rendimiento del sistema, pudiendo aceptar muchas más conexiones sin resentirse. Además todo el sistema es escalable según necesidades y con una configuración no muy difícil por lo que he estado leyendo.

Así que sin más, voy a aprovechar la tarde para salir de dudas y tener un primer contacto con node y mongodb mientras suena el Live in Santa Barbara de Bob Marley.

Mientras se descarga mongodb, instalo node.js, el cual no tiene mucha historia para instalar.

Una vez instalado node, ejecutar el comando:

npm search

Aparecerá un listado con los módulos disponibles.
Mientras sigue descargando mongo, he encontrado el siguiente tutorial.

Creating a REST API using Node.js, Express, and MongoDB

Tiene buena pita, así que me basaré en el para mi primer contacto.


INSTALANDO MONGODB


CReo una carpeta en la raíz llamada mongodb y copio ahi todo el contenido de la instalación de mongodb

Creo otras carpetas /data/db tambien en la raíz, quedando la estructura que sigue:




Sólo queda ejecutar el mongod, que es el proceso del servidor.

mongod


Ya podemos acceder a mongoDB:


mongo



Me arroja algunos avisos, ya que estoy probando desde WinXP 32 bits, pero para lo que quiero ver, sobrado.


ESTRUCTURA DE DIRECTORIOS




Creo una carpeta en la raíz

node_blog



Dentro meto un archivo llamado server.js, que será el servidor:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Primera prueba\n');
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');







Ahora sólo tenemos que probar ejecutándolo:

node server.js

Si apuntamos un navegador a localhost:3000 tendría que abrirse mostrando el mensaje:





Para instalar express, crearemos un archivo package.json con el siguiente contenido:



{
"name": "blog",
"description": "Blog basico",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "3.x"
}
}
Entramos al directorio node_blog y desde linea de comandos y ejecutamos:
npm install

Esto crea la instalación de express en el directorio de nuestra aplicacion.

AL LIO

Ahora que todo está instalado, podemos modificar el server.js para que use express:


var express = require('express');
var app = express();
app.get('/articulos', function(req, res) {
    res.send([{nombre:'articulo1'}, {nombre:'articulo2'}]);
});
app.get('/articulos/:id', function(req, res) {
    res.send({id:req.params.id, nombre: "Nombre articulo", descripcion: "Descripcion articulo"});
});
app.listen(3000);
console.log('Servidor escuchando en el puerto 3000...');



Ejecuta de nuevo el server y prueba lo siguiente:

localhost:3000/articulos   - para ver una lista de los articulos
localhost:3000/articulos/1 - para ver un articulo en concreto

Para mantener el código separado vamos a independizar  el código necesario para los artículos del server, ya que sería engorroso si continuamos metiendo en el mismo archivo todo el código necesario para nuestro sistema.

Creo una carpeta en el proyecto llamada 'routes'.

Dentro, creo un archivo, con el nombre articulos.js con el siguiente codigo:


exports.findAll = function(req, res) {
    res.send([{nombre:'articulo1'}, {nombre:'articulo2'}, {nombre:'articulo3'}]);
};

exports.findById = function(req, res) {
    res.send({id:req.params.id, nombre: "Nombre articulo", descripcion: "Descripcion articulo"});
};


Modificamos nuestro server:


var express = require('express');

var articulos = require('./routes/articulos.js');


var app = express();


app.get('/articulos', articulos.findAll);
app.get('/articulos/:id', articulos.findById);

app.listen(3000);
console.log('Servidor escuchando en el puerto 3000...');



Reiniciamos el server de nuevo y probamos... Bastante más simple  y fácil de mantener.


UTILIZAR LOS DATOS DE MONGODB


Necesitamos instalar el driver de mongodb para node:

Nos vamos a la carpeta de nuestro programa (node_blog) y desde la línea de comandos ponemos:

npm install mongodb

Finalmente, los dos archivos necesarios para nuestra aplicación quedan como sigue:


articulos.js


var mongo = require('mongodb');

var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;

var server = new Server('localhost', 27017, {auto_reconnect: true});
db = new Db('blog', server);

db.open(function(err, db) {
    if(!err) {
        console.log("Conectado a blog");
        db.collection('articulos', {strict:true}, function(err, collection) {
            if (err) {
                console.log("La coleccion articulos no existe. Creando articulos de ejemplo...");
                populateDB();
            }
        });
    }
});



exports.findById = function(req, res) {
    var id = req.params.id;
    console.log('Recuperando articulo: ' + id);
    db.collection('articulos', function(err, collection) {
        collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
            res.send(item);
        });
    });
};

exports.findAll = function(req, res) {
    db.collection('articulos', function(err, collection) {
        collection.find().toArray(function(err, items) {
            res.send(items);
        });
    });
};

exports.addArticulo = function(req, res) {
    var articulo = req.body;
    console.log('Insertando articulo: ' + JSON.stringify(articulo));
    db.collection('articulos', function(err, collection) {
        collection.insert(articulo, {safe:true}, function(err, result) {
            if (err) {
                res.send({'error':'Ocurrio un error'});
            } else {
                console.log('Insertado: ' + JSON.stringify(result[0]));
                res.send(result[0]);
            }
        });
    });
}

 exports.updateArticulo = function(req, res) {
    var id = req.params.id;
    var articulo = req.body;
    console.log('Actualizando articulo: ' + id);
    console.log(JSON.stringify(articulo));
    db.collection('articulos', function(err, collection) {
        collection.update({'_id':new BSON.ObjectID(id)}, articulo, {safe:true}, function(err, result) {
            if (err) {
                console.log('Error actualizando: ' + err);
                res.send({'error':'Ocurrio un error'});
            } else {
                console.log('' + result + ' actualizado');
                res.send(articulo);
            }
        });
    });
}

exports.deleteArticulo = function(req, res) {
    var id = req.params.id;
    console.log('Borrando articulo: ' + id);
    db.collection('articulos', function(err, collection) {
        collection.remove({'_id':new BSON.ObjectID(id)}, {safe:true}, function(err, result) {
            if (err) {
                res.send({'error':'Ocurrio un error - ' + err});
            } else {
                console.log('' + result + ' borrado');
                res.send(req.body);
            }
        });
    });
}




var populateDB = function() {

    var articulos = [
    {
        nombre: "NODE.JS",
        fecha: "06/04/2013",
        description: "Para pensarselo",
        imagen: "node.jpg"
    },
    {
        nombre: "MONGODB",
        fecha: "06/04/2013",
        description: "En ello estamos",
        imagen: "mongo.jpg"
    },
{
        nombre: "express",
        fecha: "06/04/2013",
        description: "A ver como funciona",
        imagen: "express.jpg"


}];

    db.collection('articulos', function(err, collection) {
        collection.insert(articulos, {safe:true}, function(err, result) {});
    });

};


server.js


var express = require('express');

var articulos = require('./routes/articulos.js');

var app = express();

app.get('/articulos', articulos.findAll);
app.get('/articulos/:id', articulos.findById);
app.post('/articulos', articulos.addArticulo);
app.put('/articulos/:id', articulos.updateArticulo);
app.delete('/articulos/:id', articulos.deleteArticulo);

app.listen(3000);
console.log('Servidor escuchando en el puerto 3000...');





Aunque el tutorial que he seguido está bastante claro,  me quedan muchas dudas sobre cómo y si necesito realizar el cambio a este sistema.

De todas formas sólo estoy rascando la superficie y aún me queda mucho por ver.

Así que el siguiente paso será leer sobre MongoJS, otro módulo para node que permite acceder a MongoDB al estilo de su shell en javascript.

Intentaremos buscar otra tarde libre...

No hay comentarios:

Publicar un comentario