Cómo iniciar un servidor de nodos: ejemplos con los marcos más populares

¿Sabía que hay varias formas de iniciar un servidor Node.js y mantenerlo en funcionamiento? En esta publicación, exploraremos varias formas de iniciar un servicio de nodo HTTP...

Hello World con un servidor Node.js

¿Sabía que hay varias formas de iniciar un servidor Node.js y mantenerlo en funcionamiento? En esta publicación, exploraremos varias formas de iniciar un servidor de nodo HTTP.

Un servidor Node.js hace que su aplicación esté disponible para atender solicitudes HTTP. Proporciona la interacción entre los usuarios y su aplicación.

Crear e iniciar un servidor es fácil con el módulo http incorporado de Node.js.

En un archivo app.js, cree y guarde el siguiente código de creación de servidor:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// app.js

const http = require('http');

// Create an instance of the http server to handle HTTP requests
let app = http.createServer((req, res) => {
    // Set a response type of plain text for the response
    res.writeHead(200, {'Content-Type': 'text/plain'});

    // Send back a response and end the connection
    res.end('Hello World!\n');
});

// Start the server on port 3000
app.listen(3000, '127.0.0.1');
console.log('Node server running on port 3000');

En tu terminal, ejecuta el comando:

1
$ node app.js

y visite http://localhost:3000 en su navegador.

Hello, World!{.img-responsive}

Debería ver que nuestro servidor se está ejecutando y que aparece el texto "¡Hola, mundo!" en su navegador. Creamos una instancia de un servidor HTTP utilizando el módulo http integrado. Este es un servidor simple pero muy poderoso que puede manejar solicitudes, emitir respuestas y mucho más.

Podemos ver el poder adicional del servidor HTTP básico al extenderlo de la siguiente manera para transmitir un archivo de video. Primero, en el mismo directorio con su archivo app.js, cree un nuevo directorio llamado assets. Dentro de activos, coloque un archivo de video mp4 de su elección. Luego, ajuste la nueva lista de códigos a continuación para reemplazar el nombre de mi video con el nombre exacto de su video.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// app.js

const http = require('http');
const fs = require('fs');     // to help serve a local video file

// Create an instance of the http server to handle HTTP requests
let app = http.createServer((req, res) => {
    // Set a response type of mp4 video for the response
    res.writeHead(200, {'Content-Type': 'video/mp4'});

    // Read the video into a stream
    let vidstream = fs.createReadStream('assets/Yngwie_Malmsteen_interview.mp4');

    // Pipe our stream into the response
    vidstream.pipe(res);
});

// Start the server on port 3000
app.listen(3000, '127.0.0.1');
console.log('Node server running on port 3000');

Ahora, cuando reinicie el servidor y visite la aplicación en el navegador, verá que nuestro servidor ahora está transmitiendo un archivo de video.

Streaming video{.img-responsive}

Otras opciones para iniciar un servidor con Node.js

Uso de otros módulos de servidor

También podemos iniciar un servidor Node usando el módulo npm servidor. Tenga en cuenta que este módulo requiere la versión 7.6.0 o posterior de Node.

En un proyecto nuevo, instale el módulo con el comando npm install server --save. Luego crea un archivo app.js con los siguientes contenidos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// app.js

const server = require('server');

const { get, post } = server.router;

// Launch server
server({ port: 3000 }, [
    get('/', ctx => 'Hello world!')
]);

Ejecutar el servidor con

1
$ node app.js

En su navegador, debería ver el texto "¡Hola mundo!".

Si todo lo que desea es un servidor Node.js para servir HTML y archivos estáticos sin tener que codificar nada para el servidor, Node también tiene una solución para eso. En este caso, debe instalar el servidor de línea de comandos de configuración cero servidor http para servir sus archivos.

Para usar http-server, instálelo con el comando npm install http-server -g.

En un directorio nuevo, cree un directorio secundario llamado público en el que colocaremos archivos estáticos para que los sirva http-server. Cree un archivo HTML estático dentro de este directorio público llamado index.html con los siguientes contenidos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- public/index.html -->
<html>
  <head>
    <title>Hello from http-server</title>
  </head>
  <body>

    <h1>Hello, World!</h1>

   </body>
</html>

Luego puede ejecutar el http-server usando el comando:

1
$ http-server ./public

Visite http://localhost:8081 para verificar que el servidor se está ejecutando y sirve nuestro archivo con el mensaje "Hello World". Esta opción de servicio de Node.js es útil para servir una aplicación simple que realiza principalmente trabajo de front-end.

Mantener los servidores en funcionamiento para siempre {#mantener los servidores en funcionamiento para siempre}

Otro escenario surge cuando tiene un servidor Node.js en ejecución que desea que siga ejecutándose automáticamente. Siempre lo ayudará a mantener los servidores Node funcionando incluso después de reiniciar el sistema operativo. También reinicia su aplicación después de un bloqueo, lo que la hace útil para monitorear y reiniciar servidores Node.

Mantenga los servidores funcionando con PM2

PM2 es una alternativa a forever que mantiene las aplicaciones ejecutándose entre reinicios del servidor. También tiene un equilibrador de carga incorporado para mejorar el tiempo de actividad. Es un poco más potente, pero también complicado, por lo que puede no ser adecuado para principiantes.

Cómo ayudan los marcos para iniciar un servidor de nodos

Además de las opciones para ejecutar servidores que discutimos anteriormente, también puede ejecutar un servidor utilizando el código proporcionado por el propio marco. Los marcos brindan ventajas como buenas convenciones predeterminadas y la capacidad de desarrollar rápidamente sin escribir rutinas de software comunes desde cero.

A lista de los marcos de Node más populares based on GitHub stars includes the following:

En las siguientes secciones, mostraremos cómo iniciar un servidor Node utilizando algunas de estas opciones populares.

Framework 1: iniciar un servidor de nodo con Express

Expresar es el framework web minimalista más conocido para Node.js. Es adecuado para todo tipo de aplicaciones, desde pequeñas hasta grandes. Debido a que deja la mayoría de las opciones al desarrollador, es bueno para los desarrolladores experimentados.

Para comenzar, cree una nueva carpeta de proyecto con un archivo dentro denominado app.js.

A continuación, instale Express con lo siguiente:

1
$ npm install express

Ahora actualice app.js de la siguiente manera para iniciar un servidor Node usando Express.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// app.js
const express = require('express')

// Create Express app
const app = express()

// A sample route
app.get('/', (req, res) => res.send('Hello World!'))

// Start the Express server
app.listen(3000, () => console.log('Server running on port 3000!'))

Ejecute el servidor con el comando:

1
$ node app.js

y visite http://localhost:3000 para ver el servidor Express en acción.

Framework 2: iniciar un servidor de nodos con Koa.js

Koa es un marco minimalista de los creadores de Express. Su objetivo es ser más simple, incluso menos obstinado y más expresivo. Como tal, se recomienda para los desarrolladores que desean un enfoque más purista que incluso el que ofrece Express.

Instalar Koa con:

1
$ npm i koa

Cree la siguiente aplicación Koa mínima dentro de un nuevo archivo, app.js.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// app.js
const Koa = require('koa');

// Create Koa app
const app = new Koa();

// Serve requests, here, printing out a simple greeting
app.use(async ctx => {
    ctx.body = 'Hello World';
});

// Start the server
app.listen(3000);

Ejecute este servidor ejecutando:

1
$ node app.js

Luego visite http://localhost:3000 en su navegador para ver el servidor ejecutándose. Será recibido por el mismo texto de respuesta que vimos cuando ejecutamos el servidor Express.

Framework 3: node un servidor con Socket.io

Zócalo.io es un framework de Nodos en tiempo real. Es particularmente ventajoso cuando está desarrollando aplicaciones de mensajería y chat. La plataforma funciona igual de bien para otras aplicaciones que involucran llamadas bidireccionales basadas en eventos.

Cree un nuevo proyecto e instale Socket.io con el comando:

1
$ npm install --save socket.io

También instale Express, que usaremos para integrar con Socket.io, usando el comando:

1
$ npm install --save [correo electrónico protegido]

Luego crea un archivo index.js con lo siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// index.js
// Require and create our server packages
let app = require('express')();
let http = require('http').Server(app);
let io = require('socket.io')(http);

// Send socket initialization scripts to the client
app.get('/', function(req, res){
    res.send(`
<script src="/socket.io/socket.io.js"></script>
<script>
    let socket = io();
    socket.on('text', (txt) => {
        let textp = document.createElement("h1");
        let t = document.createTextNode(txt);
        textp.appendChild(t);                                            
        document.body.appendChild(textp);
    });
</script>`);
});

// Respond to socket connections with a Hello World text
io.on('connection', (socket) => {
    console.log('User connected');
    io.emit('text', 'Hello, World!');
});

// Run our socket-enabled server
http.listen(3000, function() {
    console.log('listening on *:3000');
});

Lo que esto hace es crear una instancia de socket.io adjunta a nuestro servidor Express. Cuando los clientes se conectan al socket, nuestro servidor socket.io devuelve un saludo "Hola, mundo" a través de la conexión del socket. Para ver los resultados, ejecute el siguiente comando:

1
$ node index.js

Framework 4: Servidor con Diet.js

dieta.js es un micromarco para escribir API y aplicaciones modulares de Node.js. Permite la creación de hosts virtuales y otras características interesantes. Querrá considerarlo como una alternativa a los marcos minimalistas como Express. El núcleo del marco es solo 450 [SLOC] (https://en.wikipedia.org/wiki/Source_lines_of_code). Se integra con una amplia variedad de middleware que se ejecuta en Node.js.

Para iniciar un servidor usando Diet.js, cree un nuevo proyecto e instale Diet.js con:

1
$ npm install diet

Luego, crea un archivo fuente index.js con el siguiente código:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// index.js
const server = require('diet');

// Create a diet server
let app = server();

// Start the server on port 3000
app.listen('http://localhost:3000');

// Serve the home route
app.get('/', ($) => {
    // Respond with a greeting and end the request
    $.end('Hello, World!');
});

Inicie el servidor con el comando:

1
$ node index.js

Y luego visite http://localhost:3000 para ver el servidor en ejecución.

Diet.js tiene una API simple, que combina muchos conceptos de Express en una API e implementación más simples. Esto reduce la curva de aprendizaje para desarrollar una aplicación simple. Si tiene en mente una aplicación más grande, los marcos más estructurados como Sails.js podrían ser más adecuados para usted.

Framework 5: iniciar un servidor de nodo con Sails.js

Paño es la respuesta de Node.js a marcos MVC con todas las funciones como Ruby on Rails. Su uso de las capacidades en tiempo real de Node.js lo hace adecuado para aplicaciones que usan websockets y mensajería. Viene con planos que facilitan la creación rápida de prototipos de un backend con muy poco código.

Vamos a crear un nuevo directorio nuevo e instalar Sails con lo siguiente:

1
$ npm install sails -g

Esto instala Sails globalmente en su sistema. Luego, crea una aplicación Sails con el comando $ sails new helloapp. Dentro de la carpeta helloapp recién creada, ejecuta el servidor Sails con el comando:

1
$ sails lift

Visite http://localhost:1337 para ver la aplicación a nivel local.

Sails generó una aplicación completa con el comando sails new. La aplicación se inicializa en el archivo app.js, que tiene los siguientes contenidos generados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * app.js
 *
 * Use `app.js` to run your app without `sails lift`.
 * To start the server, run: `node app.js`.
 *
 * This is handy in situations where the sails CLI is not relevant or useful.
 *
 * For example:
 *   => `node app.js`
 *   => `forever start app.js`
 *   => `node debug app.js`
 *   => `modulus deploy`
 *   => `heroku scale`
 *
 *
 * The same command-line arguments are supported, e.g.:
 * `node app.js --silent --port=80 --prod`
 */


// Ensure we're in the project directory, so cwd-relative paths work as expected
// no matter where we actually lift from.
// > Note: This is not required in order to lift, but it is a convenient default.
process.chdir(__dirname);

// Attempt to import `sails`.
var sails;
try {
  sails = require('sails');
} catch (e) {
  console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
  console.error('To do that, run `npm install sails`');
  console.error('');
  console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
  console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
  console.error('but if it doesn\'t, the app will run with the global sails instead!');
  return;
}

// --•
// Try to get `rc` dependency (for loading `.sailsrc` files).
var rc;
try {
  rc = require('rc');
} catch (e0) {
  try {
    rc = require('sails/node_modules/rc');
  } catch (e1) {
    console.error('Could not find dependency: `rc`.');
    console.error('Your `.sailsrc` file(s) will be ignored.');
    console.error('To resolve this, run:');
    console.error('npm install rc --save');
    rc = function () { return {}; };
  }
}


// Start server
sails.lift(rc('sails'));

El código de inicialización importa Sails, luego carga la aplicación e inicia el servidor Sails.

Sails tiene la ventaja de ser particularmente rápido y escalable. En este punto de referencia contra Rails, Sails se desempeñó hasta 3x-4x más rápido. La parte crítica del rendimiento de Sails para aplicaciones a escala tiende a ser la base de datos, donde la paginación y los índices se pueden usar para acelerar las cosas.

Framework 6: uso de MEAN.io para un servidor de nodo

MEAN.io es uno de los marcos JavaScript de pila completa más conocidos. Es una variante del llamado "MEAN Stack", siendo MEAN.js otra variante. MEAN usa MongoDB, Express, Angular y Node.js.

Para iniciar una aplicación MEAN.io, clone la implementación de referencia de la aplicación modelo MEAN.io usando el comando:

1
$ git clone https://github.com/linnovate/mean.git  

Suggested Course: Domina el MEAN Stack - Aprende con el ejemplo

Alternativamente, puede clonar en otro directorio de su elección. Luego cambie al nuevo directorio mean o al directorio elegido e instale las dependencias con:

1
$ npm install

Ejecute la aplicación con npm start y visite http://localhost:4040 para verla en acción.

El código para configurar el servidor se encuentra en el archivo server\\config\\express.js que contiene lo siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import express from 'express';
import logger from 'morgan';
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
import compress from 'compression';
import methodOverride from 'method-override';
import cors from 'cors';
import httpStatus from 'http-status';
import expressWinston from 'express-winston';
import expressValidation from 'express-validation';
import helmet from 'helmet';
import winstonInstance from './winston';
import routes from '../routes/index.route';
import config from './config';
import APIError from '../helpers/APIError';
import path from 'path';
import appRoot from 'app-root-path';
import innograph from 'innograph'
import postCtrl from '../controllers/post.controller';


const app = express();

if (config.env === 'development') {
  app.use(logger('dev'));
}

// parse body params and attache them to req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use(cookieParser());
app.use(compress());
app.use(methodOverride());

// secure apps by setting various HTTP headers
app.use(helmet());

// enable CORS - Cross Origin Resource Sharing
app.use(cors());

// enable detailed API logging in dev env
if (config.env === 'development') {
  expressWinston.requestWhitelist.push('body');
  expressWinston.responseWhitelist.push('body');
  // app.use(expressWinston.logger({
  //   winstonInstance,
  //   meta: true, // optional: log meta data about request (defaults to true)
  //   msg: 'HTTP {{req.method}} {{req.url}} {{res.statusCode}} {{res.responseTime}}ms',
  //   colorStatus: true // Color the status code (default green, 3XX cyan, 4XX yellow, 5XX red).
  // }));
}
app.use(express.static(path.join(appRoot.path, 'dist')));

app.use('/api', routes);

innograph.init('/api/graphql', app, {post: postCtrl});

app.get('*', (req, res) => {
  res.sendFile(path.join(appRoot.path, 'dist/index.html'));
});

// if error is not an instanceOf APIError, convert it.
app.use((err, req, res, next) => {
  if (err instanceof expressValidation.ValidationError) {
    // validation error contains errors which is an array of error each containing message[]
    const unifiedErrorMessage = err.errors.map(error => error.messages.join('. ')).join(' and ');
    const error = new APIError(unifiedErrorMessage, err.status, true);
    return next(error);
  } else if (!(err instanceof APIError)) {
    const apiError = new APIError(err.message, err.status, err.isPublic);
    return next(apiError);
  }
  return next(err);
});

// catch 404 and forward to error handler
app.use((req, res, next) => {
  const err = new APIError('API not found', httpStatus.NOT_FOUND);
  return next(err);
});

// log error in winston transports except when executing test suite
if (config.env !== 'test') {
  app.use(expressWinston.errorLogger({
    winstonInstance
  }));
}

// error handler, send stacktrace only during development
app.use((err, req, res, next) => // eslint-disable-line no-unused-vars
  res.status(err.status).json({
    message: err.isPublic ? err.message : httpStatus[err.status],
    stack: config.env === 'development' ? err.stack : {}
  })
);

export default app;

En el corazón de la pila MEAN se encuentra un servidor Express que utiliza el middleware Node como analizador de cuerpo para procesar las cargas útiles de las solicitudes, [Winston](https:// www.npmjs.com/package/winston) para el registro de solicitudes y casco para proteger las solicitudes HTTP.

Las ventajas de MEAN incluyen estar basado en tecnologías sólidas que tienen una capacidad comprobada para impulsar aplicaciones de alto tráfico. La aplicación de referencia integra MongoDB, así como Angular y React. También usa Typescript, junto con algunos componentes de ejemplo para que pueda usarlos como punto de partida. Si no necesita una determinada biblioteca, puede eliminarla de las dependencias en el archivo package.json.

Framework 7: Inicie un servidor de nodos con LoopBack, el marco API

Bucle invertido es un marco de Node que le permite crear rápidamente aplicaciones centradas en API. Tiene partes automatizadas del proceso de creación de API, lo que hace posible generar API RESTful con poca o ninguna codificación. Loopback combina un conjunto de módulos que puede integrar a medida que aumentan los requisitos de su aplicación. Esto le permite crear aplicaciones de forma modular utilizando módulos Loopback estándar.

Puede instalar Loopback globalmente con el comando:

1
$ npm install -g loopback-cli

Para crear un proyecto, ejecute lb, que lo guiará a través de la creación de una aplicación Loopback básica.

Elija la aplicación hello-world para incluir un mensaje y un controlador simples. Las otras opciones son crear una API o un proyecto que contenga un ejemplo de trabajo básico con una base de datos de memoria.

Ir con el tipo de aplicación hello-world genera una aplicación básica. Dentro del archivo "server/server.js" encontrarás el siguiente código generado:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
'use strict';

var loopback = require('loopback');
var boot = require('loopback-boot');

var app = module.exports = loopback();

app.start = function() {
  // start the web server
  return app.listen(function() {
    app.emit('started');
    var baseUrl = app.get('url').replace(/\/$/, '');
    console.log('Web server listening at: %s', baseUrl);
    if (app.get('loopback-component-explorer')) {
      var explorerPath = app.get('loopback-component-explorer').mountPath;
      console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
    }
  });
};

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
  if (err) throw err;

  // start the server if `$ node server.js`
  if (require.main === module)
    app.start();
});

Este código inicializa el servidor Loopback, que puede iniciar con el comando nodo. Visite http://localhost:3000 para verificar que el servidor se está ejecutando. También puede consultar http://localhost:3000/explorador para ver la interfaz de la API Loopback.

Nuestra API está vacía para empezar. Crear un nuevo modelo y puntos finales REST es fácil con Loopback CLI. Ejecute el comando modelo lb y escriba un nombre de modelo como "película", pero sin las comillas.

Luego, ajuste los valores de persistencia y otras configuraciones de acuerdo con el aviso o acepte los valores predeterminados.

Cree algunas propiedades del modelo y defina los tipos de datos. Por ejemplo, una película puede tener un título que será una cadena. Ingrese tantas propiedades como desee y luego finalice.

Ahora contamos con una API para películas, a la cual puedes acceder con una solicitud GET a http://localhost:3000/api/películas. Esto devolverá una matriz JSON vacía. Puede explorar la API con el explorador de API en http://localhost:3000/explorador.

Cree algunas películas y luego interactúe con la API en el navegador para ver el servidor Loopback en acción. Además, mire el código fuente generado para la API. Loopback hace que el desarrollo de API sea realmente fácil.

Elegir el mejor servidor de nodo para su aplicación

Elegir la mejor manera de servir su aplicación Node.js implica una serie de compensaciones. Desarrollar su propio marco basado en el módulo http es práctico, dada la amplia gama de middleware que puede integrar con una aplicación de Node. Esta ruta le brinda la capacidad de tomar todas las decisiones usted mismo sobre cómo funcionará su aplicación.

Ir con un marco como Socket.io o Sails le permite construir sobre una base probada que otros han usado con éxito. La amplia gama de marcos también le permite reutilizar el código de estas bibliotecas para comenzar un poco más rápido.

La contrapartida con los marcos, en particular los que tienen opiniones como Sails, es que algunas de las opciones técnicas ya están hechas para usted. Si desea algo fuera de la norma para la que está optimizado el marco, podría tener dificultades. Koa y Express ofrecen un término medio seguro donde se han hecho muy pocas elecciones o suposiciones sobre su aplicación.

Aquí hay una guía rápida para seleccionar el marco que le permite construir de manera efectiva según las necesidades de su aplicación:

Descripción de la aplicación Marco sugerido


Sin suposiciones, enfoque minimalista, modular Diet.js, Koa, Express Base de código grande, se ajusta a ciertas convenciones, MEAN.io escalable Chat, mensajería Socket.io Blueprints listos para usar y convenciones muy sólidas, centrados en API, algunos "mágicos" Sails.js, Loopback