Menu iconMenu icon
JavaScript from Zero to Superhero

Chapter 11: JavaScript and the Server

11.2 Building a REST API with Express

As you continue your journey in exploring the depths of server-side JavaScript, you will find that one of the most common and powerful applications of Node.js is in creating RESTful APIs. REST, which stands for Representational State Transfer, is a widely-accepted architectural style that capitalizes on standard HTTP methods such as GET, POST, PUT, and DELETE for communication. This style is employed in the development of web services, and it facilitates the interaction between client and server in a seamless manner.

On the other hand, Express.js, often simply referred to as Express, is a minimalistic and flexible web application framework for Node.js. It is designed with the concept of simplicity and flexibility in mind, allowing developers to build web and mobile applications with ease.

Its robust set of features allows for the creation of single, multi-page, and hybrid web applications, thus making it an incredibly efficient tool for building REST APIs. With Express.js, developers can write less code, avoid repetition, and ultimately, save time. Its flexibility and minimalism, coupled with the power of Node.js, make for a feature-rich environment that is conducive for the development of robust web and mobile applications.

11.2.1 Why Express?

Express simplifies the process of building server-side applications with Node.js. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js due to its simplicity and the vast middleware ecosystem available.

The primary reason behind Express's popularity is its simplicity. It provides a straightforward and intuitive way of defining routes and handlers for various HTTP requests and responses. This simplicity accelerates the development process and allows developers to build applications more efficiently.

Express also introduces the concept of middleware. Middleware functions are essentially pieces of code that have access to the request object, the response object, and the next middleware function in the application’s request-response cycle. They can execute any code, modify the request and response objects, end the request-response cycle, or call the next middleware function in the stack. This architecture allows developers to perform a wide variety of tasks, from managing cookies, parsing request bodies, to logging and more, simply by plugging in the appropriate middleware.

Moreover, Express is known for its scalability. Its lightweight nature, combined with the ability to manage server-side logic efficiently and integrate seamlessly with databases and other tools, makes Express an excellent choice for scaling applications. As the application's requirements grow, Express can easily handle the increased load, ensuring the application remains robust and performant.

Express has a large and active community. This means that it's easy to find solutions to problems, learn from others' experiences, and access a vast array of middleware and tools developed by the community. This support network can be invaluable for both novice and experienced developers.

In summary, Express simplifies the development of server-side applications with Node.js by providing a simple, scalable, and flexible framework with a robust middleware ecosystem. Its active community also ensures support and continuous development, making it an excellent choice for building web applications and APIs.

Key Features of Express:

  • Simplicity: Express.js offers an uncomplicated, straightforward way to set up routes that your API can use for effective communication with clients. The simplicity of Express.js allows developers to handle requests and responses without unnecessary complexity, thus enhancing productivity.
  • Middleware: Express.js has a robust middleware framework which allows developers to use existing middleware to add functionality to Express applications. Alternatively, you can write your own middleware to perform an array of functions like parsing request bodies, handling cookies, managing sessions or logging. This flexibility empowers developers to extend the functionality of their applications as per their specific needs.
  • Scalability: Express.js exhibits efficient handling of server-side logic and offers seamless integration with databases and other tools, making it an excellent choice for scaling applications. Its lightweight architecture and high performance make it the preferred choice for developing applications that can handle a large number of requests without sacrificing speed or performance.

11.2.2 Setting Up an Express Project

To start, you'll need Node.js installed on your system. Then, you can set up an Express project with some initial setup:

mkdir myapi
cd myapi
npm init -y
npm install express

Los comandos crean un nuevo directorio llamado 'myapi', navegan dentro de ese directorio, inicializan un nuevo proyecto Node.js con configuraciones predeterminadas (debido al indicador '-y'), y luego instalan la biblioteca Express.js, que es un marco popular para construir aplicaciones web en Node.js.

Crea un archivo llamado app.js y añade la siguiente configuración básica:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.send('Hello World from Express!');
});

app.listen(PORT, () => {
    console.log(`Server running on <http://localhost>:${PORT}`);
});

El fragmento de código de ejemplo utiliza el marco de Express.js, un marco de aplicación web Node.js popular y flexible, para configurar un servidor web simple.

En primer lugar, importa el módulo 'express'. Esto se logra utilizando la función require(), que es una función integrada en Node.js utilizada para importar módulos (bibliotecas o archivos). El módulo 'express' importado se almacena luego en la variable constante 'app'.

A continuación, se configura una variable constante 'PORT'. Esta variable se asigna al valor de la variable de entorno 'PORT' si existe, o por defecto a 3000 si no existe. Esto se hace utilizando el operador '||' (OR lógico). Las variables de entorno son un mecanismo universal para transmitir información de configuración a los programas Unix. Forman parte del entorno en el que se ejecuta un proceso.

La función app.get() se utiliza luego para configurar una ruta para solicitudes HTTP GET. En este caso, especifica que cuando el servidor reciba una solicitud GET en la URL raíz ('/'), debe ejecutar la función de devolución de llamada proporcionada. La función de devolución de llamada toma dos argumentos: 'req' (el objeto de solicitud) y 'res' (el objeto de respuesta). En este caso, la función simplemente utiliza 'res.send()' para enviar la cadena 'Hola Mundo desde Express!' de vuelta al cliente que hace la solicitud.

Finalmente, se llama a app.listen() con la constante 'PORT' como argumento, lo que le indica al servidor que comience a escuchar conexiones entrantes en ese puerto. Este método también toma una función de devolución de llamada como argumento, que se ejecutará una vez que el servidor comience a escuchar con éxito. En este caso, registra un mensaje en la consola, indicando que el servidor está funcionando y en qué puerto, utilizando una cadena de plantilla e incluyendo la variable 'PORT' dentro de ella.

Ejecuta tu aplicación usando node app.js y visita http://localhost:3000 para verla en acción.

11.2.3 Construyendo una API REST Simple

Ampliemos nuestra aplicación para incluir una API REST para un recurso simple, como los usuarios.

Paso 1: Define Datos y Rutas

Primero, crea un arreglo simple para servir como nuestra base de datos:

let users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
];

A continuación, define rutas para manejar operaciones CRUD:

// Get all users
app.get('/users', (req, res) => {
    res.status(200).json(users);
});

// Get a single user by id
app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else res.status(200).json(user);
});

// Create a new user
app.use(express.json()); // Middleware to parse JSON bodies
app.post('/users', (req, res) => {
    const user = {
        id: users.length + 1,
        name: req.body.name
    };
    users.push(user);
    res.status(201).send(user);
});

// Update existing user
app.put('/users/:id', (req, res) => {
    let user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else {
        user.name = req.body.name;
        res.status(200).send(user);
    }
});

// Delete a user
app.delete('/users/:id', (req, res) => {
    users = users.filter(u => u.id !== parseInt(req.params.id));
    res.status(204).send();
});

Este código de ejemplo define varios puntos finales HTTP para un recurso de usuario:

  • GET /users: Este punto final recupera todos los usuarios. Cuando se realiza una solicitud GET a '/users', la función responde con el estado 200 (OK) y envía de vuelta el array 'users' en formato JSON.
  • GET /users/:id: Este punto final recupera un único usuario por su ID. La ID se accede a través de los parámetros de ruta en el objeto de solicitud. La función luego encuentra al usuario en el array 'users' que coincide con esta ID. Si se encuentra un usuario, la función responde con el estado 200 y envía de vuelta al usuario en formato JSON. Si no se encuentra un usuario, responde con el estado 404 (No Encontrado) y envía un mensaje de 'Usuario no encontrado'.
  • POST /users: Este punto final crea un nuevo usuario. El middleware 'express.json()' se utiliza para analizar los cuerpos de las solicitudes JSON entrantes, permitiendo que la función acceda al nombre solicitado a través de 'req.body.name'. Se crea un nuevo objeto de usuario con una ID de 'users.length + 1' y el nombre solicitado, y este usuario se añade al array 'users'. La función responde con el estado 201 (Creado) y envía de vuelta al nuevo usuario.
  • PUT /users/:id: Este punto final actualiza el nombre de un usuario existente por su ID. Similar al punto final GET '/users/', la función encuentra al usuario con la ID coincidente. Si se encuentra un usuario, actualiza el nombre del usuario con el nombre solicitado y responde con el estado 200, enviando de vuelta al usuario actualizado. Si no se encuentra un usuario, responde con el estado 404 y un mensaje de 'Usuario no encontrado'.
  • DELETE /users/:id: Este punto final elimina a un usuario por su ID. La función filtra el array 'users' para eliminar al usuario con la ID coincidente, eliminando efectivamente al usuario. La función luego responde con el estado 204 (Sin Contenido) y no envía de vuelta ningún contenido.

Este ejemplo proporciona una simple muestra de una API RESTful con Express.js, demostrando cómo manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. Sirve como base para construir APIs más complejas con funcionalidades adicionales como manejo de errores, autenticación, integración de bases de datos y más.

En conclusión, Express facilita la configuración de rutas y middleware, creando una estructura limpia y mantenible para tu API. Siguiendo estos pasos, has construido una API REST básica que puede manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. A medida que expandas tus aplicaciones Express, puedes integrar funcionalidades más complejas, como la conexión a bases de datos, manejo de autenticación y más. Esta configuración forma una base sobre la cual puedes construir a medida que tus aplicaciones crecen en complejidad y escala.

11.2 Building a REST API with Express

As you continue your journey in exploring the depths of server-side JavaScript, you will find that one of the most common and powerful applications of Node.js is in creating RESTful APIs. REST, which stands for Representational State Transfer, is a widely-accepted architectural style that capitalizes on standard HTTP methods such as GET, POST, PUT, and DELETE for communication. This style is employed in the development of web services, and it facilitates the interaction between client and server in a seamless manner.

On the other hand, Express.js, often simply referred to as Express, is a minimalistic and flexible web application framework for Node.js. It is designed with the concept of simplicity and flexibility in mind, allowing developers to build web and mobile applications with ease.

Its robust set of features allows for the creation of single, multi-page, and hybrid web applications, thus making it an incredibly efficient tool for building REST APIs. With Express.js, developers can write less code, avoid repetition, and ultimately, save time. Its flexibility and minimalism, coupled with the power of Node.js, make for a feature-rich environment that is conducive for the development of robust web and mobile applications.

11.2.1 Why Express?

Express simplifies the process of building server-side applications with Node.js. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js due to its simplicity and the vast middleware ecosystem available.

The primary reason behind Express's popularity is its simplicity. It provides a straightforward and intuitive way of defining routes and handlers for various HTTP requests and responses. This simplicity accelerates the development process and allows developers to build applications more efficiently.

Express also introduces the concept of middleware. Middleware functions are essentially pieces of code that have access to the request object, the response object, and the next middleware function in the application’s request-response cycle. They can execute any code, modify the request and response objects, end the request-response cycle, or call the next middleware function in the stack. This architecture allows developers to perform a wide variety of tasks, from managing cookies, parsing request bodies, to logging and more, simply by plugging in the appropriate middleware.

Moreover, Express is known for its scalability. Its lightweight nature, combined with the ability to manage server-side logic efficiently and integrate seamlessly with databases and other tools, makes Express an excellent choice for scaling applications. As the application's requirements grow, Express can easily handle the increased load, ensuring the application remains robust and performant.

Express has a large and active community. This means that it's easy to find solutions to problems, learn from others' experiences, and access a vast array of middleware and tools developed by the community. This support network can be invaluable for both novice and experienced developers.

In summary, Express simplifies the development of server-side applications with Node.js by providing a simple, scalable, and flexible framework with a robust middleware ecosystem. Its active community also ensures support and continuous development, making it an excellent choice for building web applications and APIs.

Key Features of Express:

  • Simplicity: Express.js offers an uncomplicated, straightforward way to set up routes that your API can use for effective communication with clients. The simplicity of Express.js allows developers to handle requests and responses without unnecessary complexity, thus enhancing productivity.
  • Middleware: Express.js has a robust middleware framework which allows developers to use existing middleware to add functionality to Express applications. Alternatively, you can write your own middleware to perform an array of functions like parsing request bodies, handling cookies, managing sessions or logging. This flexibility empowers developers to extend the functionality of their applications as per their specific needs.
  • Scalability: Express.js exhibits efficient handling of server-side logic and offers seamless integration with databases and other tools, making it an excellent choice for scaling applications. Its lightweight architecture and high performance make it the preferred choice for developing applications that can handle a large number of requests without sacrificing speed or performance.

11.2.2 Setting Up an Express Project

To start, you'll need Node.js installed on your system. Then, you can set up an Express project with some initial setup:

mkdir myapi
cd myapi
npm init -y
npm install express

Los comandos crean un nuevo directorio llamado 'myapi', navegan dentro de ese directorio, inicializan un nuevo proyecto Node.js con configuraciones predeterminadas (debido al indicador '-y'), y luego instalan la biblioteca Express.js, que es un marco popular para construir aplicaciones web en Node.js.

Crea un archivo llamado app.js y añade la siguiente configuración básica:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.send('Hello World from Express!');
});

app.listen(PORT, () => {
    console.log(`Server running on <http://localhost>:${PORT}`);
});

El fragmento de código de ejemplo utiliza el marco de Express.js, un marco de aplicación web Node.js popular y flexible, para configurar un servidor web simple.

En primer lugar, importa el módulo 'express'. Esto se logra utilizando la función require(), que es una función integrada en Node.js utilizada para importar módulos (bibliotecas o archivos). El módulo 'express' importado se almacena luego en la variable constante 'app'.

A continuación, se configura una variable constante 'PORT'. Esta variable se asigna al valor de la variable de entorno 'PORT' si existe, o por defecto a 3000 si no existe. Esto se hace utilizando el operador '||' (OR lógico). Las variables de entorno son un mecanismo universal para transmitir información de configuración a los programas Unix. Forman parte del entorno en el que se ejecuta un proceso.

La función app.get() se utiliza luego para configurar una ruta para solicitudes HTTP GET. En este caso, especifica que cuando el servidor reciba una solicitud GET en la URL raíz ('/'), debe ejecutar la función de devolución de llamada proporcionada. La función de devolución de llamada toma dos argumentos: 'req' (el objeto de solicitud) y 'res' (el objeto de respuesta). En este caso, la función simplemente utiliza 'res.send()' para enviar la cadena 'Hola Mundo desde Express!' de vuelta al cliente que hace la solicitud.

Finalmente, se llama a app.listen() con la constante 'PORT' como argumento, lo que le indica al servidor que comience a escuchar conexiones entrantes en ese puerto. Este método también toma una función de devolución de llamada como argumento, que se ejecutará una vez que el servidor comience a escuchar con éxito. En este caso, registra un mensaje en la consola, indicando que el servidor está funcionando y en qué puerto, utilizando una cadena de plantilla e incluyendo la variable 'PORT' dentro de ella.

Ejecuta tu aplicación usando node app.js y visita http://localhost:3000 para verla en acción.

11.2.3 Construyendo una API REST Simple

Ampliemos nuestra aplicación para incluir una API REST para un recurso simple, como los usuarios.

Paso 1: Define Datos y Rutas

Primero, crea un arreglo simple para servir como nuestra base de datos:

let users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
];

A continuación, define rutas para manejar operaciones CRUD:

// Get all users
app.get('/users', (req, res) => {
    res.status(200).json(users);
});

// Get a single user by id
app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else res.status(200).json(user);
});

// Create a new user
app.use(express.json()); // Middleware to parse JSON bodies
app.post('/users', (req, res) => {
    const user = {
        id: users.length + 1,
        name: req.body.name
    };
    users.push(user);
    res.status(201).send(user);
});

// Update existing user
app.put('/users/:id', (req, res) => {
    let user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else {
        user.name = req.body.name;
        res.status(200).send(user);
    }
});

// Delete a user
app.delete('/users/:id', (req, res) => {
    users = users.filter(u => u.id !== parseInt(req.params.id));
    res.status(204).send();
});

Este código de ejemplo define varios puntos finales HTTP para un recurso de usuario:

  • GET /users: Este punto final recupera todos los usuarios. Cuando se realiza una solicitud GET a '/users', la función responde con el estado 200 (OK) y envía de vuelta el array 'users' en formato JSON.
  • GET /users/:id: Este punto final recupera un único usuario por su ID. La ID se accede a través de los parámetros de ruta en el objeto de solicitud. La función luego encuentra al usuario en el array 'users' que coincide con esta ID. Si se encuentra un usuario, la función responde con el estado 200 y envía de vuelta al usuario en formato JSON. Si no se encuentra un usuario, responde con el estado 404 (No Encontrado) y envía un mensaje de 'Usuario no encontrado'.
  • POST /users: Este punto final crea un nuevo usuario. El middleware 'express.json()' se utiliza para analizar los cuerpos de las solicitudes JSON entrantes, permitiendo que la función acceda al nombre solicitado a través de 'req.body.name'. Se crea un nuevo objeto de usuario con una ID de 'users.length + 1' y el nombre solicitado, y este usuario se añade al array 'users'. La función responde con el estado 201 (Creado) y envía de vuelta al nuevo usuario.
  • PUT /users/:id: Este punto final actualiza el nombre de un usuario existente por su ID. Similar al punto final GET '/users/', la función encuentra al usuario con la ID coincidente. Si se encuentra un usuario, actualiza el nombre del usuario con el nombre solicitado y responde con el estado 200, enviando de vuelta al usuario actualizado. Si no se encuentra un usuario, responde con el estado 404 y un mensaje de 'Usuario no encontrado'.
  • DELETE /users/:id: Este punto final elimina a un usuario por su ID. La función filtra el array 'users' para eliminar al usuario con la ID coincidente, eliminando efectivamente al usuario. La función luego responde con el estado 204 (Sin Contenido) y no envía de vuelta ningún contenido.

Este ejemplo proporciona una simple muestra de una API RESTful con Express.js, demostrando cómo manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. Sirve como base para construir APIs más complejas con funcionalidades adicionales como manejo de errores, autenticación, integración de bases de datos y más.

En conclusión, Express facilita la configuración de rutas y middleware, creando una estructura limpia y mantenible para tu API. Siguiendo estos pasos, has construido una API REST básica que puede manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. A medida que expandas tus aplicaciones Express, puedes integrar funcionalidades más complejas, como la conexión a bases de datos, manejo de autenticación y más. Esta configuración forma una base sobre la cual puedes construir a medida que tus aplicaciones crecen en complejidad y escala.

11.2 Building a REST API with Express

As you continue your journey in exploring the depths of server-side JavaScript, you will find that one of the most common and powerful applications of Node.js is in creating RESTful APIs. REST, which stands for Representational State Transfer, is a widely-accepted architectural style that capitalizes on standard HTTP methods such as GET, POST, PUT, and DELETE for communication. This style is employed in the development of web services, and it facilitates the interaction between client and server in a seamless manner.

On the other hand, Express.js, often simply referred to as Express, is a minimalistic and flexible web application framework for Node.js. It is designed with the concept of simplicity and flexibility in mind, allowing developers to build web and mobile applications with ease.

Its robust set of features allows for the creation of single, multi-page, and hybrid web applications, thus making it an incredibly efficient tool for building REST APIs. With Express.js, developers can write less code, avoid repetition, and ultimately, save time. Its flexibility and minimalism, coupled with the power of Node.js, make for a feature-rich environment that is conducive for the development of robust web and mobile applications.

11.2.1 Why Express?

Express simplifies the process of building server-side applications with Node.js. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js due to its simplicity and the vast middleware ecosystem available.

The primary reason behind Express's popularity is its simplicity. It provides a straightforward and intuitive way of defining routes and handlers for various HTTP requests and responses. This simplicity accelerates the development process and allows developers to build applications more efficiently.

Express also introduces the concept of middleware. Middleware functions are essentially pieces of code that have access to the request object, the response object, and the next middleware function in the application’s request-response cycle. They can execute any code, modify the request and response objects, end the request-response cycle, or call the next middleware function in the stack. This architecture allows developers to perform a wide variety of tasks, from managing cookies, parsing request bodies, to logging and more, simply by plugging in the appropriate middleware.

Moreover, Express is known for its scalability. Its lightweight nature, combined with the ability to manage server-side logic efficiently and integrate seamlessly with databases and other tools, makes Express an excellent choice for scaling applications. As the application's requirements grow, Express can easily handle the increased load, ensuring the application remains robust and performant.

Express has a large and active community. This means that it's easy to find solutions to problems, learn from others' experiences, and access a vast array of middleware and tools developed by the community. This support network can be invaluable for both novice and experienced developers.

In summary, Express simplifies the development of server-side applications with Node.js by providing a simple, scalable, and flexible framework with a robust middleware ecosystem. Its active community also ensures support and continuous development, making it an excellent choice for building web applications and APIs.

Key Features of Express:

  • Simplicity: Express.js offers an uncomplicated, straightforward way to set up routes that your API can use for effective communication with clients. The simplicity of Express.js allows developers to handle requests and responses without unnecessary complexity, thus enhancing productivity.
  • Middleware: Express.js has a robust middleware framework which allows developers to use existing middleware to add functionality to Express applications. Alternatively, you can write your own middleware to perform an array of functions like parsing request bodies, handling cookies, managing sessions or logging. This flexibility empowers developers to extend the functionality of their applications as per their specific needs.
  • Scalability: Express.js exhibits efficient handling of server-side logic and offers seamless integration with databases and other tools, making it an excellent choice for scaling applications. Its lightweight architecture and high performance make it the preferred choice for developing applications that can handle a large number of requests without sacrificing speed or performance.

11.2.2 Setting Up an Express Project

To start, you'll need Node.js installed on your system. Then, you can set up an Express project with some initial setup:

mkdir myapi
cd myapi
npm init -y
npm install express

Los comandos crean un nuevo directorio llamado 'myapi', navegan dentro de ese directorio, inicializan un nuevo proyecto Node.js con configuraciones predeterminadas (debido al indicador '-y'), y luego instalan la biblioteca Express.js, que es un marco popular para construir aplicaciones web en Node.js.

Crea un archivo llamado app.js y añade la siguiente configuración básica:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.send('Hello World from Express!');
});

app.listen(PORT, () => {
    console.log(`Server running on <http://localhost>:${PORT}`);
});

El fragmento de código de ejemplo utiliza el marco de Express.js, un marco de aplicación web Node.js popular y flexible, para configurar un servidor web simple.

En primer lugar, importa el módulo 'express'. Esto se logra utilizando la función require(), que es una función integrada en Node.js utilizada para importar módulos (bibliotecas o archivos). El módulo 'express' importado se almacena luego en la variable constante 'app'.

A continuación, se configura una variable constante 'PORT'. Esta variable se asigna al valor de la variable de entorno 'PORT' si existe, o por defecto a 3000 si no existe. Esto se hace utilizando el operador '||' (OR lógico). Las variables de entorno son un mecanismo universal para transmitir información de configuración a los programas Unix. Forman parte del entorno en el que se ejecuta un proceso.

La función app.get() se utiliza luego para configurar una ruta para solicitudes HTTP GET. En este caso, especifica que cuando el servidor reciba una solicitud GET en la URL raíz ('/'), debe ejecutar la función de devolución de llamada proporcionada. La función de devolución de llamada toma dos argumentos: 'req' (el objeto de solicitud) y 'res' (el objeto de respuesta). En este caso, la función simplemente utiliza 'res.send()' para enviar la cadena 'Hola Mundo desde Express!' de vuelta al cliente que hace la solicitud.

Finalmente, se llama a app.listen() con la constante 'PORT' como argumento, lo que le indica al servidor que comience a escuchar conexiones entrantes en ese puerto. Este método también toma una función de devolución de llamada como argumento, que se ejecutará una vez que el servidor comience a escuchar con éxito. En este caso, registra un mensaje en la consola, indicando que el servidor está funcionando y en qué puerto, utilizando una cadena de plantilla e incluyendo la variable 'PORT' dentro de ella.

Ejecuta tu aplicación usando node app.js y visita http://localhost:3000 para verla en acción.

11.2.3 Construyendo una API REST Simple

Ampliemos nuestra aplicación para incluir una API REST para un recurso simple, como los usuarios.

Paso 1: Define Datos y Rutas

Primero, crea un arreglo simple para servir como nuestra base de datos:

let users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
];

A continuación, define rutas para manejar operaciones CRUD:

// Get all users
app.get('/users', (req, res) => {
    res.status(200).json(users);
});

// Get a single user by id
app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else res.status(200).json(user);
});

// Create a new user
app.use(express.json()); // Middleware to parse JSON bodies
app.post('/users', (req, res) => {
    const user = {
        id: users.length + 1,
        name: req.body.name
    };
    users.push(user);
    res.status(201).send(user);
});

// Update existing user
app.put('/users/:id', (req, res) => {
    let user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else {
        user.name = req.body.name;
        res.status(200).send(user);
    }
});

// Delete a user
app.delete('/users/:id', (req, res) => {
    users = users.filter(u => u.id !== parseInt(req.params.id));
    res.status(204).send();
});

Este código de ejemplo define varios puntos finales HTTP para un recurso de usuario:

  • GET /users: Este punto final recupera todos los usuarios. Cuando se realiza una solicitud GET a '/users', la función responde con el estado 200 (OK) y envía de vuelta el array 'users' en formato JSON.
  • GET /users/:id: Este punto final recupera un único usuario por su ID. La ID se accede a través de los parámetros de ruta en el objeto de solicitud. La función luego encuentra al usuario en el array 'users' que coincide con esta ID. Si se encuentra un usuario, la función responde con el estado 200 y envía de vuelta al usuario en formato JSON. Si no se encuentra un usuario, responde con el estado 404 (No Encontrado) y envía un mensaje de 'Usuario no encontrado'.
  • POST /users: Este punto final crea un nuevo usuario. El middleware 'express.json()' se utiliza para analizar los cuerpos de las solicitudes JSON entrantes, permitiendo que la función acceda al nombre solicitado a través de 'req.body.name'. Se crea un nuevo objeto de usuario con una ID de 'users.length + 1' y el nombre solicitado, y este usuario se añade al array 'users'. La función responde con el estado 201 (Creado) y envía de vuelta al nuevo usuario.
  • PUT /users/:id: Este punto final actualiza el nombre de un usuario existente por su ID. Similar al punto final GET '/users/', la función encuentra al usuario con la ID coincidente. Si se encuentra un usuario, actualiza el nombre del usuario con el nombre solicitado y responde con el estado 200, enviando de vuelta al usuario actualizado. Si no se encuentra un usuario, responde con el estado 404 y un mensaje de 'Usuario no encontrado'.
  • DELETE /users/:id: Este punto final elimina a un usuario por su ID. La función filtra el array 'users' para eliminar al usuario con la ID coincidente, eliminando efectivamente al usuario. La función luego responde con el estado 204 (Sin Contenido) y no envía de vuelta ningún contenido.

Este ejemplo proporciona una simple muestra de una API RESTful con Express.js, demostrando cómo manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. Sirve como base para construir APIs más complejas con funcionalidades adicionales como manejo de errores, autenticación, integración de bases de datos y más.

En conclusión, Express facilita la configuración de rutas y middleware, creando una estructura limpia y mantenible para tu API. Siguiendo estos pasos, has construido una API REST básica que puede manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. A medida que expandas tus aplicaciones Express, puedes integrar funcionalidades más complejas, como la conexión a bases de datos, manejo de autenticación y más. Esta configuración forma una base sobre la cual puedes construir a medida que tus aplicaciones crecen en complejidad y escala.

11.2 Building a REST API with Express

As you continue your journey in exploring the depths of server-side JavaScript, you will find that one of the most common and powerful applications of Node.js is in creating RESTful APIs. REST, which stands for Representational State Transfer, is a widely-accepted architectural style that capitalizes on standard HTTP methods such as GET, POST, PUT, and DELETE for communication. This style is employed in the development of web services, and it facilitates the interaction between client and server in a seamless manner.

On the other hand, Express.js, often simply referred to as Express, is a minimalistic and flexible web application framework for Node.js. It is designed with the concept of simplicity and flexibility in mind, allowing developers to build web and mobile applications with ease.

Its robust set of features allows for the creation of single, multi-page, and hybrid web applications, thus making it an incredibly efficient tool for building REST APIs. With Express.js, developers can write less code, avoid repetition, and ultimately, save time. Its flexibility and minimalism, coupled with the power of Node.js, make for a feature-rich environment that is conducive for the development of robust web and mobile applications.

11.2.1 Why Express?

Express simplifies the process of building server-side applications with Node.js. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js due to its simplicity and the vast middleware ecosystem available.

The primary reason behind Express's popularity is its simplicity. It provides a straightforward and intuitive way of defining routes and handlers for various HTTP requests and responses. This simplicity accelerates the development process and allows developers to build applications more efficiently.

Express also introduces the concept of middleware. Middleware functions are essentially pieces of code that have access to the request object, the response object, and the next middleware function in the application’s request-response cycle. They can execute any code, modify the request and response objects, end the request-response cycle, or call the next middleware function in the stack. This architecture allows developers to perform a wide variety of tasks, from managing cookies, parsing request bodies, to logging and more, simply by plugging in the appropriate middleware.

Moreover, Express is known for its scalability. Its lightweight nature, combined with the ability to manage server-side logic efficiently and integrate seamlessly with databases and other tools, makes Express an excellent choice for scaling applications. As the application's requirements grow, Express can easily handle the increased load, ensuring the application remains robust and performant.

Express has a large and active community. This means that it's easy to find solutions to problems, learn from others' experiences, and access a vast array of middleware and tools developed by the community. This support network can be invaluable for both novice and experienced developers.

In summary, Express simplifies the development of server-side applications with Node.js by providing a simple, scalable, and flexible framework with a robust middleware ecosystem. Its active community also ensures support and continuous development, making it an excellent choice for building web applications and APIs.

Key Features of Express:

  • Simplicity: Express.js offers an uncomplicated, straightforward way to set up routes that your API can use for effective communication with clients. The simplicity of Express.js allows developers to handle requests and responses without unnecessary complexity, thus enhancing productivity.
  • Middleware: Express.js has a robust middleware framework which allows developers to use existing middleware to add functionality to Express applications. Alternatively, you can write your own middleware to perform an array of functions like parsing request bodies, handling cookies, managing sessions or logging. This flexibility empowers developers to extend the functionality of their applications as per their specific needs.
  • Scalability: Express.js exhibits efficient handling of server-side logic and offers seamless integration with databases and other tools, making it an excellent choice for scaling applications. Its lightweight architecture and high performance make it the preferred choice for developing applications that can handle a large number of requests without sacrificing speed or performance.

11.2.2 Setting Up an Express Project

To start, you'll need Node.js installed on your system. Then, you can set up an Express project with some initial setup:

mkdir myapi
cd myapi
npm init -y
npm install express

Los comandos crean un nuevo directorio llamado 'myapi', navegan dentro de ese directorio, inicializan un nuevo proyecto Node.js con configuraciones predeterminadas (debido al indicador '-y'), y luego instalan la biblioteca Express.js, que es un marco popular para construir aplicaciones web en Node.js.

Crea un archivo llamado app.js y añade la siguiente configuración básica:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
    res.send('Hello World from Express!');
});

app.listen(PORT, () => {
    console.log(`Server running on <http://localhost>:${PORT}`);
});

El fragmento de código de ejemplo utiliza el marco de Express.js, un marco de aplicación web Node.js popular y flexible, para configurar un servidor web simple.

En primer lugar, importa el módulo 'express'. Esto se logra utilizando la función require(), que es una función integrada en Node.js utilizada para importar módulos (bibliotecas o archivos). El módulo 'express' importado se almacena luego en la variable constante 'app'.

A continuación, se configura una variable constante 'PORT'. Esta variable se asigna al valor de la variable de entorno 'PORT' si existe, o por defecto a 3000 si no existe. Esto se hace utilizando el operador '||' (OR lógico). Las variables de entorno son un mecanismo universal para transmitir información de configuración a los programas Unix. Forman parte del entorno en el que se ejecuta un proceso.

La función app.get() se utiliza luego para configurar una ruta para solicitudes HTTP GET. En este caso, especifica que cuando el servidor reciba una solicitud GET en la URL raíz ('/'), debe ejecutar la función de devolución de llamada proporcionada. La función de devolución de llamada toma dos argumentos: 'req' (el objeto de solicitud) y 'res' (el objeto de respuesta). En este caso, la función simplemente utiliza 'res.send()' para enviar la cadena 'Hola Mundo desde Express!' de vuelta al cliente que hace la solicitud.

Finalmente, se llama a app.listen() con la constante 'PORT' como argumento, lo que le indica al servidor que comience a escuchar conexiones entrantes en ese puerto. Este método también toma una función de devolución de llamada como argumento, que se ejecutará una vez que el servidor comience a escuchar con éxito. En este caso, registra un mensaje en la consola, indicando que el servidor está funcionando y en qué puerto, utilizando una cadena de plantilla e incluyendo la variable 'PORT' dentro de ella.

Ejecuta tu aplicación usando node app.js y visita http://localhost:3000 para verla en acción.

11.2.3 Construyendo una API REST Simple

Ampliemos nuestra aplicación para incluir una API REST para un recurso simple, como los usuarios.

Paso 1: Define Datos y Rutas

Primero, crea un arreglo simple para servir como nuestra base de datos:

let users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 3, name: 'Charlie' }
];

A continuación, define rutas para manejar operaciones CRUD:

// Get all users
app.get('/users', (req, res) => {
    res.status(200).json(users);
});

// Get a single user by id
app.get('/users/:id', (req, res) => {
    const user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else res.status(200).json(user);
});

// Create a new user
app.use(express.json()); // Middleware to parse JSON bodies
app.post('/users', (req, res) => {
    const user = {
        id: users.length + 1,
        name: req.body.name
    };
    users.push(user);
    res.status(201).send(user);
});

// Update existing user
app.put('/users/:id', (req, res) => {
    let user = users.find(u => u.id === parseInt(req.params.id));
    if (!user) res.status(404).send('User not found');
    else {
        user.name = req.body.name;
        res.status(200).send(user);
    }
});

// Delete a user
app.delete('/users/:id', (req, res) => {
    users = users.filter(u => u.id !== parseInt(req.params.id));
    res.status(204).send();
});

Este código de ejemplo define varios puntos finales HTTP para un recurso de usuario:

  • GET /users: Este punto final recupera todos los usuarios. Cuando se realiza una solicitud GET a '/users', la función responde con el estado 200 (OK) y envía de vuelta el array 'users' en formato JSON.
  • GET /users/:id: Este punto final recupera un único usuario por su ID. La ID se accede a través de los parámetros de ruta en el objeto de solicitud. La función luego encuentra al usuario en el array 'users' que coincide con esta ID. Si se encuentra un usuario, la función responde con el estado 200 y envía de vuelta al usuario en formato JSON. Si no se encuentra un usuario, responde con el estado 404 (No Encontrado) y envía un mensaje de 'Usuario no encontrado'.
  • POST /users: Este punto final crea un nuevo usuario. El middleware 'express.json()' se utiliza para analizar los cuerpos de las solicitudes JSON entrantes, permitiendo que la función acceda al nombre solicitado a través de 'req.body.name'. Se crea un nuevo objeto de usuario con una ID de 'users.length + 1' y el nombre solicitado, y este usuario se añade al array 'users'. La función responde con el estado 201 (Creado) y envía de vuelta al nuevo usuario.
  • PUT /users/:id: Este punto final actualiza el nombre de un usuario existente por su ID. Similar al punto final GET '/users/', la función encuentra al usuario con la ID coincidente. Si se encuentra un usuario, actualiza el nombre del usuario con el nombre solicitado y responde con el estado 200, enviando de vuelta al usuario actualizado. Si no se encuentra un usuario, responde con el estado 404 y un mensaje de 'Usuario no encontrado'.
  • DELETE /users/:id: Este punto final elimina a un usuario por su ID. La función filtra el array 'users' para eliminar al usuario con la ID coincidente, eliminando efectivamente al usuario. La función luego responde con el estado 204 (Sin Contenido) y no envía de vuelta ningún contenido.

Este ejemplo proporciona una simple muestra de una API RESTful con Express.js, demostrando cómo manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. Sirve como base para construir APIs más complejas con funcionalidades adicionales como manejo de errores, autenticación, integración de bases de datos y más.

En conclusión, Express facilita la configuración de rutas y middleware, creando una estructura limpia y mantenible para tu API. Siguiendo estos pasos, has construido una API REST básica que puede manejar diversas solicitudes HTTP, manipular datos y responder a los clientes de manera efectiva. A medida que expandas tus aplicaciones Express, puedes integrar funcionalidades más complejas, como la conexión a bases de datos, manejo de autenticación y más. Esta configuración forma una base sobre la cual puedes construir a medida que tus aplicaciones crecen en complejidad y escala.