1. Introducción
Hola y bienvenidos a todos a un nuevo post de nuestro querido blog!. En esta ocasión nos vamos a adentrar en el mundo de NodeJS. La idea principal va a ser crear nuestro primer proyecto en esta tecnología. Para ello instalaremos node, crearemos un proyecto utilizando express y levantaremos nuestra primera aplicación. He de admitir que éste es un post especial ya que es la primera vez que aparcamos nuestro querido mundo Java para adentrarnos en otros universos.
Node.js es un entorno multiplataforma basado en el lenguaje de programación ECMAScript, asíncrono, orientada a eventos y basado en el motor V8 de Google. Fue creado por Ryan Dahl en 2009 y su evolución está apadrinada por la empresa Joyent. Entre las características mas destacables podemos señalar:
- Basado en Javascript en el servidor
- Rápido desarrollo
- Flexible
- Escalable
- Modularizable gracias a su gestor de paquetes npm
- Basado en eventos
Os podéis descargar el código de ejemplo de mi GitHub aquí.
Tecnologías empleadas:
- NodeJS 6.11.0
- Npm 3.10.10
- Express 4.15.2
2. Instalación y preparación del entorno
Lo primero que tenemos que hacer es descargarnos el ejecutable de NodeJS de la web oficial https://nodejs.org para proceder con la instalación. Una vez terminado tendremos disponibles los siguientes elementos en nuestra máquina:
- nodejs. Core a través del cual podremos ejecutar nuestras aplicaciones en servidor escritas en javascript
- npm. Gestor de paquetes a través del cual gestionaremos nuestras dependencias
Para verificar que la instalación se ha realizado de forma correcta bastará con hacer
3. Creación del proyecto
Utilizamos las conocidos módulos express y express-generator para generar la estructura de nuestro proyecto web.
Los instalamos de forma global.
Finalmente creamos nuestro proyecto que denominamos NodeJsMongoDBHelloWorld
Quedando una estructura de carpetas tal que así:
En el fichero package.json se defines los módulos que vamos a necesitar en nuestra aplicación.
{ "name": "nodejsmongodbhelloworld", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.17.1", "cookie-parser": "~1.4.3", "debug": "~2.6.3", "express": "~4.15.2", "jade": "~1.11.0", "morgan": "~1.8.1", "serve-favicon": "~2.4.2" } }
Dichas dependencias deben ser instaladas para que se puedan ser utilizadas en tiempo de compilación. Para ello bastará con hacer:
Una vez finalizado el comando anterior deberíamos ver los diferentes módulos descargados en el directorio node_modules
4. Arranque del proyecto
Para arrancar nuestra primera aplicación node es suficiente con ejecutar el siguiente comando desde un terminal situándonos en la raiz del proyecto.
y entrar en la url http://localhost:3000
5. Análisis de los ficheros principales
El fichero principal de nuestro proyecto es el app.js en donde se definen la ubicación de las vistas, el motor que las resuelve (se utiliza por defecto jade), los controladores de nuestra aplicación o los tipos de formato que se van a aceptar.
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var index = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
Los controladores se definen con convenio en los ficheros route en donde establecemos la función que se debe ejecutar en función del método y la url invocada.
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); module.exports = router;
var express = require('express'); var router = express.Router(); /* GET users listing. */ router.get('/', function(req, res, next) { res.send('respond with a resource'); }); module.exports = router;
Por otra parte las vistas las podemos encontrar en el directorio views
doctype html html head title= title link(rel='stylesheet', href='/stylesheets/style.css') body block content
Hemos indicado anteriormente que para llevar a cabo el arranque del servidor web debemos utilizar el comando npm start
sobre un terminal. Esto arrancará un script que se define en el fichero package.json "start": "node ./bin/www"
#!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('nodejsmongodbhelloworld:server'); var http = require('http'); /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); }
Una de las cosas que más llama la atención es que, a diferencia de otras tecnologías como Java donde para levantar un servidor web necesitamos un Tomcat o un servidor de aplicaciones, en nodejs el servidor lo creamos en el arranque de la aplicación.