Construyendo un sistema de comentarios sencillo con Node.js, Express, Jade y Stylus.
Por Daniel R. @sadasant.
Últimamente me he estado iniciando con Node.js, se trata de un entorno JavaScript fuera del navegador web, pero basado en el motor V8 de Google Chrome, que permite hacer servidores web. ¿Por qué Node.js?: Los motivos son varios, por un lado significa tener un mismo lenguaje del lado del cliente y de lado del servidor, por lo que se puede reutilizar el código. Por otro lado, Node.js, tal como el JavaScript en los navegadores, está orientado a eventos, por lo que una vez se encuentra en ejecución, el usuario al recargar la página no obliga al servidor a volver a ejecutar el código, sino que el pedido es atendido por un proceso ya en ejecución. Por último, node es un boom, una ola que en los últimos años ha crecido muy rápidamente.
Como principal excusa les digo que, para mi, el solo hecho de poder escribir JavaScript en una consola me trae una sonrisa al rostro :)
En el tutorial de hoy les explicaré cómo hacer sitios sencillos muy rápidamente con una serie de herramientas ya creadas y bastante sencillas de aprender, llegaremos hasta el punto de hacer un sistema de comentarios ni dinámico, ni seguro, pero que demostrará parte de las ventajas de Node.js como servidor web.
1. Instalando las dependencias
Primero que nada, necesitamos node.js, si están en algún ambiente Linux seguramente podrán hacer alguna línea similar a estas:
En fedora:
yum install nodeEn Arch Linux:
pacman -S nodejs
También puedes leer las alternativas que puse en un tutorial anterior que hice sobre Node.js: aquí.
Una vez con node, nos tocará instalar el manejador de paquetes de node, npm, para lo que en ambientes Unix/Linux podemos hacer lo siguiente:
curl http://npmjs.org/install.sh | sh
Lo siguiente que haremos es empezar a cargar los módulos que necesitaremos, en este caso usaremos los siguientes:
express: Marco de trabajo para el desarrollo web con Node.js.
jade: Es un lenguaje de plantillas que permite agilizar enormemente el proceso de hacer páginas de contenido dinámicas con variables en el servidor.
stylus: Es un meta-lenguaje para CSS que nos permitirá quitar los dos puntos, el punto y coma, las comas, los paréntesis, utilizar variables, interpolación, aritmética, condicionales, funciones, selectores anidados (selectores dentro de selectores (inception)), referencia a los selectores padres, entre otras cosas.
Para instalarlos, una vez tenemos npm es tan sencillo como ingresar a la carpeta de nuestro proyecto actual y ejecutar lo siguiente en consola:
npm install express jade stylus
npm descargará todo el código necesario dentro de la carpeta node_modules en el directorio actual.
Con esto ya podríamos importar alguno de estos módulos de la siguiente manera:
var express = require('express');
2. Configurando el directorio local.
Ya listas las dependencias, el primer es crear una configuración por defecto con todos los módulos que usaremos, para lo cual podemos ejecutar en consola lo siguiente:
./node_modules/express/bin/express -t jade -c stylus
Al ejecutarlo nos preguntará si queremos proceder, responderemos con una y y nos dirá lo siguiente:
destination is not empty, continue? y
create : .
create : ./package.json
create : ./app.js
create : ./views
create : ./views/layout.jade
create : ./views/index.jade
create : ./public/javascripts
create : ./public/images
create : ./public/stylesheets
create : ./public/stylesheets/style.styl
Podemos probar la configuración básica al ejecutar app.js con node:
node app.js
Para ver los resultados, tendremos que ir con el navegador a: http://localhost:3000/
3. Analizando el código generado.
Ahora, entendamos como funciona Express. Para esto es importante tener a mano la guía de Express, que nos permitirá ir entendiendo las líneas que aparecerán al abrir app.js.
Las primeras dos líneas importan el módulo, crean un servidor web y lo guardan en dos variables, la primera es module.exports y la segunda es app.
/**
* Module dependencies.
*/
var express = require('express');
var app = module.exports = express.createServer();
Tanto app como module.exports tendrán el controlador del servidor que usaremos. module.exports contendrá todas las variables que podrán ser leídas por otros módulos cuando estos importen nuestro código, es decir, una vez inicializada esa variable podríamos escribir otro programa con var server = require('app'); y tendremos en la variable server el contenido de express.createServer();.
Luego nos encontramos con la configuración:
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(require('stylus').middleware({ src: __dirname + '/public' }));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
En la primera línea del código anterior, configuramos el directorio de las vistas. Express es un marco de trabajo MVC (Modelo Vista Controlador), por lo que está separado en tres aspectos principales: Modelo (Gestión de datos), vista (Representación de los datos) y controlador (control de interacciones. En este tutorial solo mostraremos dos de estos 3 elementos: Vista y Controlador.
La segunda línea indica que el motor de vistas será Jade. Si observaron, en ningún momento importamos el módulo, pero es porque Express se encargará de eso por nosotros. Más adelante iremos en detalle con Jade.
La tercera línea app.use(express.bodyParser()); nos permitirá recolectar la data enviada por POST dentro de una variable req.body. Más adelante hablaremos sobre esto.
La cuarta línea app.use(express.methodOverride()); permite hacer cambios al método del formulario añadiendo un input oculto de nombre “_method”.
La quinta línea app.use(require('stylus').middleware({ src: __dirname + '/public' })); establece el sistema de estilos que usaremos, stylus, más adelante iremos con detalles.
La sexta línea inicializa el controlador de nuestra aplicación con app.use(app.router); y la séptima línea del código arriba expuesto app.use(express.static(__dirname + '/public')); permitirá que el controlador no interceda con las descargas dentro del directorio “public” de nuestra aplicación.
Las siguientes líneas nos permitirán separar los errores mostrados de la fase de desarrollo de nuestra aplicación con respecto a la aplicación ya publicada en producción:
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
En el caso de que queramos que nuestra aplicación funcione en modo producción, necesitamos definir la variable global NODE_ENV como production, bien lo podemos hacer para una simple ejecución de la siguiente manera:
NODE_ENV=production node app.js
Luego llegamos a las líneas del controlador, en este caso llamado enrutador (“router”), se encargará de manejar las rutas de las peticiones HTTP, orientándolas para que ejecuten funciones particulares. En este caso solo está definida la ruta principal:
app.get('/', function(req, res){
res.render('index', {
title: 'Express'
});
});
En las variables recibidas por la función, “req” y “res”, se encontrarán los datos del pedido (“req” de “request”) y la respuesta (“res” de “response”). En este caso estamos ejecutando el middlewear (Jade) que renderiza la página ‘index’, a la cual además le pasamos las variables que serán analizadas o mostradas dinámicamente.
Casi al final, nos encontramos con las líneas que le indican al servidor que escuche en un puerto determinado:
app.listen(3000);
Y un mensaje en consola para que comprobemos que funcionó la ejecución:
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
4. Jade.
Si entran en el directorio views encontrarán solo dos archivos:
index.jade layout.jade
En index se encontrará el contenido específico que se mostrará en la página principal, pero que estará embebido dentro del diseño que Jade cargará por defecto en todas las páginas, llamado: layout.jade.
Si entramos en index.jade veremos lo siguiente:
h1= title
p Welcome to #{title}
¿Cómo funciona esto?, si se fijan en el enrutador, le indicamos que para la raíz principal de nuestra aplicación (‘/’) el sistema cargaría la vista ‘index’ con una serie de parámetros, entre los cuales colocamos una variable title que contiene 'Express'. Cuando cargamos el servidor en http://localhost:3000/, tal como vimos en la imagen arriba, podemos analizar el resultado y ver que la página contiene la siguiente estructura:
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
</body>
Como ven, es lo mismo que sale en index.jade, de hecho si cambiamos el enrutador y colocamos “Comments!” en la variable title de esta manera:
app.get('/', function(req, res){
res.render('index', {
title: 'Comments!'
});
});
Veremos el siguiente resultado:
<body>
<h1>Comments!</h1>
<p>Welcome to Comments!</p>
</body>
Si abrimos layout.jade veremos lo siguiente:
!!!
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body!= body
En este caso, el layout indicará las etiquetas principales de html, como <html></html>, <head></head>, <title></title>, y además cargará el CSS desde /stylesheets/style.css. El detalle es que, en nuestro directorio principal no tenemos tal ubicación… Pues el servidor detecta esos pedidos y los extrae diréctamente desde la carpeta /public. Si la abren podrán ver que el estilo se encuentra en /public/stylesheets/style.css.
Para leer más detalles sobre Jade, pueden entrar a este enlace: https://github.com/visionmedia/jade.
5. Entendiendo Stylus.
En la dirección pública de los estilos también está un archivo llamado style.styl. Se trata de la fuente del CSS en el meta-lenguaje Stylus, si lo abrimos veremos que solo tiene las siguientes líneas:
body
padding: 50px
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
a
color: #00B7FF
En estructura se parece a CSS, pero se muestra de una manera mucho mas minimalista y reducida. Node, al ejecutarse a tiempo real, verifica si style.styl ha cambiado, y si lo ha hecho, genera el archivo style.css con el código interpretado:
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00b7ff;
}
Para leer más sobre stylus, pueden entrar a este enlace: http://learnboost.github.com/stylus/try.html.
6. Construyendo un sistema de comentarios sencillo.
¿Cómo podemos hacer un sistema de comentarios?, pues, quizás como yo, ustedes vengan desde el mundo de modelos como PHP en Apache, que se vuelven a ejecutar cada vez que actualizas la página. Node.js puede almacenar datos dentro de variables internas en tiempo de ejecución, estas se perderán si se reinicia la aplicación, pero son suficientes para hacer este ejemplo.
Primero vayamos a nuestro index.jade y creemos un formulario:
#form
form(method='post', action='newPost')
b Author:
br
input(type='text', name='author', id='author', value='')
br
br
b Content:
br
textarea(name='content', id='content')
br
br
input(type='submit', value='Post it!')
Al hacer click en “submit” se enviará a la url http://localhost:3000/newPost, que deberemos interpretar con nuestra aplicación.
Antes de seguir, tendremos que declarar una variable donde almacenaremos los comentarios:
var comments = [{ author: 'Tester', content: 'Test.' }];
Esta variable contendrá un arreglo con todos los comentarios contenidos en objetos literales con los valores author y content. Para dar un ejemplo inicial, colocamos dentro un comentario de autor “Tester” y contenido “Test.”. Una vez declarada, podemos escuchar los pedidos del formulario diciéndole al enrutador de Express que esté atento a los post en la dirección /newPost.
app.post('/newPost', function(req, res){
if (req.body.author && req.body.content) {
comments.push({ author: req.body.author, content: req.body.content });
}
return res.redirect('/');
});
Express recibirá los datos de post en req.body, en este caso le enviamos dos valores, author y content (por el input y el textarea respectivos del form), nos aseguramos de que ambos tengan valores y los añadimos a la variable global comments con: comments.push({ author: req.body.author, content: req.body.content }); y finalmente, hayamos añadido valores o no, le indicamos al enrutador que cargue la raiz de nuestra aplicación con: return res.redirect('/');.
Para asegurarnos de que en la raiz se muestren los comentarios, tenemos que insertar una línea al enrutador de la raiz:
app.get('/', function(req, res){
res.render('index', {
title: 'Comments!',
comments: comments // esta línea
});
});
Y luego recorrer los valores dentro de nuestro index.jade:
- for c in comments
#comment
- var author = c.author
- var content = c.content
small
b By #{author}
p= content
Esas líneas las coloqué después del título y antes del formulario para que se viese el formulario al final, como suele estar en los sistemas de comentarios.
Ya está casi lista, ahora mejoremos un poco el estilo. Por capricho y para mostrarle parte de las ventajas de Stylus, crearemos una función dentro de Stylus que nos de bordes redondeados para cualquier navegador, nos dirigimos a public/stylesheets/style.styl y antes de todo el código colocamos estas líneas:
vendors = webkit moz o ms official
border-radius()
for v in vendors
if v == official
border-radius: arguments
else
-{vendor}-border-radius: arguments
A la que podremos luego llamar usando tan solo border-radius: 5px.
Para terminar, le daremos un estilo determinado a todos los divs, al contenido que se encuentra en las <p></p> y a los input y textareas de nuestro sistema de comentarios:
div
border: 1px solid #ddd
border-radius: 5px
margin: 5px
padding: 5px
width: 300px
p
border-top: 1px solid #ddd
padding: 5px
margin-top: 0px
input,textarea
width: 99%
border: 1px solid #999
border-radius: 5px
Ejecutamos con nuestra cónsola node app.js y nos dirigiremos a http://localhost:3000/ para probar con nuestro navegador el sistema de comentarios que acabamos de construir:
Muchas gracias por su tiempo, espero que este tutorial les haya sido de utilidad.
Patrones para predefinir variables en funciones con JavaScript (y node.js).
Por Daniel R. @sadasant.
Hace unos días, mientras hacía unas prácticas con node.js y publicaba un tutorial, me tocó escribir una función como esta:
function getDB(db){
var user = 'usuario';
var pass = 'clave';
var host = 'localhost';
var url = 'http://'+user+':'+pass+'@'+host+':5984/'+db;
return CouchClient(url);
};
Es una función cualquiera, recibe una cadena identificada como la variable db, concatena una serie de cadenas de caracteres y luego pasa el resultado a la función CouchClient. Funciona correctamente, pero el caso es que, tener que declarar 3 variables (user, pass y host) cada vez que se ejecutase la función me parecía un desperdicio de memoria. Quizás digan que eso no importa en JavaScript, pero para aplicaciones que requieren mucho procesamiento (como juegos) quizás sería mejor que esas variables estuviesen ya predefinidas en vez de re-declararse cada vez que se vuelva a ejecutar la función.
Este tutorial explicará varias maneras (patrones de diseño) de hacer esto, esperando encontrar el patrón más cómodo (al menos para mi) para predefinir variables en funciones.
Simplificando el problema.
Crearemos un script llamado fun00.js con el siguiente código:
function fun(it){
var isFun = ' is fun!';
return it + isFun;
};
En esencia hace lo mismo, recibe una variable (en este caso it) y la concatena a una cadena (llamada isFun), para luego retornarla.
Preparándonos para probar los ejemplos.
Para probarlos desde el navegador, importamos el código al documento colocando la siguiente línea en el html:
<script src="fun.js"></script>
Y luego podremos colocar:
<script>
alert(fun('JavaScript'));
</script>
También, para tener una información más detallada, podríamos hacer lo siguiente si tenemos un debugger como Firebug:
<script>
console.debug(fun('JavaScript'));
</script>
Para probarlos en node.js, tendríamos que añadir la siguiente línea:
console.log(fun('JavaScript'));
Y luego lo ejecutamos con:
$ node fun00.js
JavaScript is fun!
En lo personal prefiero usar esta última para este tipo de ejercicios.
1. Definiendo las variables fuera de la función.
Una de las maneras más sencillas de predefinir variables es declarándolas por fuera de la función, y luego llamándola dentro. Para probarlo crearemos el programa fun01.js y le colocaremos dentro:
var isFun = ' is Fun!';
function fun(it){
return it + isFun;
};
console.log(fun('JavaScript'));
// JavaScript is fun!
Ventajas:
- Es intuitivo.
Desventajas:
- Cada vez que utilizas nombres globales para asignar variables tan simples se muere un gatito. El problema de las variables globales es que limita la extensibilidad del código, así que esto es un anti-patrón.
2. Definiendo las variables dentro de un objeto literal que además tenga la función.
Otra de las maneras de predefinir variables en funciones es colocándolas fuera de la función, pero colocando todo el conjunto de variables y funciones dentro de un objeto literal mayor.
var fun = {
isFun: ' is Fun!',
run: function (it){
return it + this.isFun;
}
};
console.log(fun.run('JavaScript'));
// JavaScript is fun!
Teniendo node.js, podríamos probarlo así:
$ node fun02.js
JavaScript is Fun!
Ventajas:
- Es intuitivo.
- Utiliza solo una variable global.
- Permite cambiar las variables predefinidas desde funciones externas.
Desventajas:
- Como la función que queda se tiene que ejecutar con la sintaxis del punto
fun.run()quizás pueda ser considerado como un nivel de abstracción innecesario cuando solo se quiere llamar a una sola función, pero que tenga variables predefinidas.
3. Definiendo las variables dentro de una función anónima que retornará la función que queremos.
Otra de las maneras es utilizando el poder de programación funcional de JavaScript. Igualamos fun a una función anónima que ejecutamos al momento, dentro de ella, declaramos isFun y luego retornamos la función que realmente queremos que esté dentro de fun. Para probar esto, crearemos el script fun03.js con estas líneas de código:
var fun = (function (){
var isFun = ' is Fun!';
return function (it) {
return it + isFun;
};
})();
Al declarar la variable dentro de la función que ejecutamos al momento, se conservará en ese campo mientras la función que retornamos no desaparezca del tiempo de ejecución (sea eliminada).isFun permanecerá solo en el campo donde fue creada, por lo que solo la podrán detectar elementos que estén en ese campo (como la función que retornamos), por medios externos será imposible cambiar ese valor.
Ventajas:
- Si te gustan las lambdas (como a mi) te gustará este método.
- Si quieres variables privadas en JavaScript, ahí tienes como hacerlo.
Desventajas:
- No es intuitivo para los novatos.
- Las variables declaradas dentro de la función que se ejecuta al momento no podrán ser modificadas ni leídas por algún otro medio que no sea la función que se retorna, por lo que puede limitar la extensibilidad del programa.
4. Definiendo las variables sólo en la primera ejecución de la función.
Otra de las maneras de predefinir variables en funciones es colocar un condicional dentro de la función que verifique que esa variable está declarada dentro del prototipo; si no lo está (será igual a undefined) la declarará (this.isFun = ' is fun!';), para lo cual creamos un nuevo script llamado fun04.js con el siguiente código:
function fun(it){
if (this.isFun == undefined) {
console.log('Setting isFun.');
this.isFun = ' is fun!';
}
return it + this.isFun;
};
Si la variable isFun no está definida en el prototipo, antes de declararla hemos colocado una línea conteniendo console.log('Setting isFun.');, lo que nos permitirá saber cuantas veces se ejecuta esa definición.
Para probarlo correctamente debemos ejecutarla dos veces, por lo que colocamos las siguientes dos líneas al final del código:
console.log(fun('Predefining'));
console.log(fun('JavaScript'));
Al ejecutar el script, en la consola nos mostrará lo siguiente:
$ node fun04.js
Setting isFun.
Predefining is fun!
JavaScript is fun!
Como vemos, solo definió la variable una vez :)
Ventajas:
- Es intuitivo.
- Si se usa para casos puntuales es perfectamente plausible.
- Da la posibilidad de ejecutar acciones durante la primera ejecución de la función.
Desventajas:
El uso excesivo de condicionales puede llegar a ser bastante criticado dentro de la comunidad porque incrementa innecesariamente la complejidad visual del código.
Usar demasiados condicionales podría hacer al programa inevitablemente imposible de mantener a largo plazo y mucho menos escalar.
5. Utilizando clases.
Para los fanáticos de la orientación a objetos, otra manera es utilizando clases en JavaScript. Crear una clase es simplemente hacer una función en donde se inicialicen nuevas variables en el prototipo (this.publicIsFun), variables que pueden contener desde datos hasta funciones y otros objetos. Una vez creada, para crear un nuevo objeto, se le asigna a una variable el resultado de new seguido del nombre de la clase, y luego se puede puede acceder a los métodos y propiedades dentro del nuevo objeto (Fun.publicFun()). Para probar esto creamos el nuevo script fun05.js y le colocamos las siguientes líneas:
function Fun (){
var privateIsFun = ' is closed fun!';
this.publicIsFun = ' is open fun!';
this.privateFun = function(it){
return it + privateIsFun;
}
this.publicFun = function(it){
return it + this.publicIsFun;
}
};
var Fun = new Fun();
// Probando en node.js
console.log(Fun.privateFun('Using private variables'));
console.log(Fun.publicFun('Using public variables'));
Al ejecutarlo con node.js nos mostraría:
$ node fun05.js
Using private variables is closed fun!
Using public variables is open fun!
Ventajas:
- Es intuitivo para quienes sepan sobre clases y objetos.
- Permite crear muchos más comportamientos que le darían muchísimo más poder al programa.
Desventajas:
- Usar un excesivo número de clases puede llegar a ser incómodo.
- A veces esos niveles de abstracción son innecesarios, en especial cuando únicamente se quiere predefinir variables para una función particular.
6. Bind.
Otro método que encontré para hacer este tipo de cosas es utilizando el método bind que tienen todas las funciones en javascript. Tal como nos cuenta la red de documentos de mozilla, bind creará una nueva función con un this igual al parámetro que se le pase a bind, por lo que podemos crear una función anónima que haga lo que queremos que haga y a esa función, antes de asignarla, ejecutar bind, al cual le pasaremos como argumento un objeto literal con las variables pre-definidas que necesitemos. Creamos otro archivo de texto llamado fun06.js con el siguiente contenido:
var fun = function(it) {
return it + this.isFun;
}.bind({
isFun: ' is fun!'
});
console.log(fun('JavaScript'));
Y lo probamos de esta manera:
$ node fun06.js
JavaScript is fun!
Todos los parámetros después del primero que se le pasen a bind serán interpretados como los primeros argumentos de la función, por lo que podríamos escribirlo de esta manera:
var fun = function(isFun, it) {
return it + isFun;
}.bind(undefined, ' is fun!');
Y nos entregaría lo mismo:
> fun('JavaScript');
'JavaScript is fun!'
Ventajas:
- Es corto y es intuitivo una vez que entendemos que hace bind.
Desventajas:
- Las variables predefinidas no se podrán editar.
7. Combinando el tercero con el segundo.
El libro “patrones de diseño para novatos” lo llaman “el patrón revelador” (Detalles en ingles aquí) podemos ver cómo utilizar el segundo ejemplo que hicimos (con objetos literales) mas el tercer método para combinar tanto las variables privadas como las públicas en un nuevo modelo de trabajo. Creamos un último script llamado fun07.js y dentro le colocamos:
var fun = (function (){
var privateIsFun = ' is closed fun!';
function privateFun(it){
return it + privateIsFun;
}
function publicFun(it){
return it + this.publicIsFun;
}
return {
publicIsFun: ' is open fun!',
privateFun: privateFun,
publicFun: publicFun
}
})();
// Probando en node.js
console.log(fun.privateFun('Using private variables'));
console.log(fun.publicFun('Using public variables'));
Al ejecutarlo con node.js nos mostraría:
$ node fun05.js
Using private variables is closed fun!
Using public variables is open fun!
Ventajas:
- Permite definir variables y/o funciones públicas y extensibles tanto como hacer que otras sean otras privadas.
- Es sumamente versátil.
Desventajas:
- No es intuitivo si no se está acostumbrado a trabajar con objetos literales o con funciones anónimas.
- No es intuitivo para quienes empiecen a programar JavaScript desde lenguajes como JAVA.
Conclusión.
¿Cuál es más conveniente? Depende de para qué lo vayas a utilizar. Por extensibilidad y sencillez quizás sea mejor el segundo, aunque el que utiliza las clases es más extenso todavía ¿Quizás prefieran el patrón revelador? ¡O bien quieren algo sencillo y hacen bind!
Sean creativos ;)
Gracias por leer este tutorial.
Empezando con Node.js y CouchDB
Por Daniel Rodríguez @sadasant.
En los últimos años han habido un par de tecnologías que han causado furor en el campo de servidores web y bases de datos NoSQL. Node.js, creado en el 2009 por Ryan Dahl consiste en un entorno JavaScript basado en el motor V8 del navegador Google Chrome, que no necesita de un navegador web y que permite de manera intuitiva servir aplicaciones web a tiempo real.
CouchDB por otro lado es un proyecto creado el 2005 por la fundación Apache, se trata de una base de datos NoSQL, orientada a documentos, que ha causado mucho interes por su API REST que permite interactuar con ella mediante URLs que retornan su contenido en formato JSON.
La idea es que hoy aprendamos a instalar node.js, el gestor de paquetes de node (NPM) y couchdb, además de hacer una prueba simple de lectura utilizando el cliente couch-client.
1. ¿Cómo instalar Node.js?
Antes que nada, es necesario asegurarnos de que tenemos todas las herramientas de compilación, tal como el compilador gcc, make, libtool, entre otros. En fedora es tan sencillo como instalar el grupo “Development Tools”:
yum groupinstall "Development Tools"
Al tener estas herramientas podemos proceder con la instalación de node.js, para lo cual necesitamos descargar el paquete desde esta URL: http://nodejs.org/#download, o bien seguir las instrucciones en el github de node, en donde indican que para ambientes Linux primero debemos ejecutar:
git clone git://github.com/joyent/node.git
cd node
./configure
make
y luego ejecutar como root:
make install
¡Y listo! Podemos probarlo ahora con:
./node -v # arrojará la versión instalada de node
Para usar node sin entrar a la carpeta donde se instaló, tenemos que entrar a nuestro perfil de bash con:
nano ~/.bashrc
Y añadir la siguiente línea, con la ubicación correcta del programa:
alias node='/home/usuario/ubicacion/de/node-v?.?.??/node'
2. NPM
NPM es un sistema de gestión de paquetes especial para node, que permite instalar módulos desde repositorios externos usando la consola de manera simple y sencilla.
Siempre y cuando tengas node.js podrás instalar NPM ejecutando en la línea de comandos de tu sistema UNIX:
curl http://npmjs.org/install.sh | sh
Puedes ver más detalles sobre el software aquí: https://github.com/isaacs/npm
3. Probando node
Al ejecutar node entraremos a una consola interactiva donde podremos ejecutar comandos de JavaScript.
[user@user folder]$ node
> (1).toString();
'1'
La diferencia entre ese javascript y el de los navegadores es que no existe el DOM (por lo que no existe el objeto document) ni las funciones útiles dentro del navegador (como alert()).
También podemos crear un archivo con código javascript y ejecutarlo con node. Por ejemplo, si escribimos en un documento llamado uno.js el siguiente código:
var uno = (1).toString();
console.log(uno);
Para ejecutarlo haríamos lo siguiente:
[user@user folder]$ node uno.js
'1'
4. Node como servidor web
El sitio web http://www.nodebeginner.org/ provee un tutorial intuitivo y práctico para inicializarnos con node.js. Por ejemplo, una de las cosas que enseña es hacer un servidor web con node, para lo que simplemente necesitamos importar el módulo http y decirle que cree un servidor que responda en algún puerto (en este caso el 8888) y que cuando sea llamado escriba hello world en texto plano, de esta manera:
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
Lo cual, al ejecutarlo con node server.js ya funcionará como un servidor web en la dirección http://localhost:8888/ :)
5. ¿Cómo instalar CouchDB?
Por lo general, en distribuciones linux como Fedora solo tenemos que hacer como root:
yum install couchdb
De no contar con ese recurso, tenemos que asegurarnos de instalar las siguientes dependencias de CouchDB con nuestro gestor de paquetes: icu, libicu-devel, js, js-devel, curl y libtool. Luego procedemos a descargarnos el código fuente desde los repositorios de apache:
svn checkout http://svn.apache.org/repos/asf/couchdb/trunk couchdb
Estamos usando svn como sistema de control de versiones para obtener la última versión de couchdb, svn viene por defecto en muchas distribuciones basadas en UNIX, si quieren descargarse los binarios en un comprimido pueden ir a https://couchdb.apache.org/downloads.html, descargar la versión que les parezca y descomprimirla.
Una vez descargados los binarios de couchdb y descomprimidos, tenemos que entrar y empezar con la compilación:
cd couchdb
./bootstrap
./configure
Luego com root:
make install
Una vez finalizada la instalación, podremos ejecutar:
/etc/init.d/couchdb start
Y entrar a la base de datos con: http://localhost:5984/_utils/index.html
También podemos conseguir una guía de cómo instalarla en Windows en el siguiente enlace: https://wiki.apache.org/couchdb/Installing_on_Windows.
6. ¿Cómo usar CouchDB desde su interfaz web?
Una vez entremos a la interfaz web de couchdb nos aparecerá en la esquina inferior derecha el siguiente texto:
Welcome to Admin Party!
Everyone is admin. Fix this
Indica que todos son administradores, lo cual es recomendable cambiar. Hacemos click en Fix this, nos aparecerá lo siguiente:
Creamos un usuario de ejemplo usuario con clave clave y le damos a crear. Lo siguiente es hacer una base de datos, para ello hay un botón en la parte superior que dice Create Database...; al darle click nos muestra:
Arriba saldrá un botón que dirá New Document, al darle click veremos esto:
Podrás cambiar la id de la base de datos y añadir campos con el botón Add Field, el cual nos permitirá cambiar la id y el contenido del campo recién añadido:
7. Probando CouchDB con Node.js
Una vez tenemos a Node.js, NPM y CouchDB instalados, podremos utilizar NPM para instalar el cliente de CouchDB dentro de node.js:
npm install couch-client
Aquí encontrarán detalles sobre el API de couch-client: https://github.com/creationix/couch-client.
Una vez instalado, el comando ejecutado creará el código necesario dentro del directorio node_modules/couch-client. Para hacer uso de este cliente, creamos un nuevo documento javascript y escribimos:
var CouchClient = require('couch-client');
Y en la variable CouchClient se guardará todo el api que necesitaremos para manipular a nuestra base de datos CouchDB. Con ella obtendremos documentos tan solo pasándole como parámetro la URL del pedido, de la siguiente manera:
var db = CouchClient('http://usuario:clave@localhost:5984/baseDeDatos');
Podríamos dinamizar el proceso creando una función que nos de cualquier base de datos de nuestra CouchDB:
/* getDB( DB )
* Obtiene la base de datos DB
* dentro de *nuestro* couchdb
*/
var getDB = function (db){
var user = 'usuario'; // usuario de la BDD
var pass = 'clave'; // clave de la BDD
var host = 'localhost'; // URL de la BDD
var url = 'http://'+user+':'+pass+'@'+host+':5984/'+db;
return CouchClient(url);
};
var db = getDB("baseDeDatos"); // le pedimos la bdd "baseDeDatos"
En el API de couch-client veremos que, una vez tenemos la base de datos, podemos pedirle cualquier documento utilizando el método get:
db.get( IDdelDocumento, callback );
Para probarlo, crearemos una variable con la ID del documento y otra variable que contenga una función que usaremos como callback, esta función puede simplemente reportar por la consola el contenido del documento, de esta manera:
var key = "28fbda6c0037c5608cecef6b2b0006fb"; // ID del documento
var callback = function (error, documento){ // callback luego de pedir el documento
console.log(error, documento);
}
db.get(key, callback); // pedimos el documento
Luego ejecutamos:
[user@user folder]$ node prueba_de_couchdb.js
null { _id: '28fbda6c0037c5608cecef6b2b0006fb',
_rev: '1-7316e80a4a688d27bc4cd2fe04916f58',
test1: null,
test2: 'lol' }
El primer null que arroja es el error del callback; a partir de la primera llame { se encuentra el resto del documento extraído de la base de datos.
Para leer sobre el resto de las capacidades del cliente de CouchDB para node pueden visitar su sitio web oficial: http://localhost:5984/_utils/index.html.
Más adelante iremos haciendo otras pruebas con estas tecnologías :) sus comentarios son bienvenidos.








