Crear una API REST en Node

Manejar endpoints con Express


En el artículo anterior vimos una Introducción a Express, con la cuál podríamos crear una API restful muy sencilla. Vamos a extender sus funcionalidades para poder hacerlo más flexible.

Verbos HTTP

Hasta ahora, en nuestro código, habíamos creado rutas de esta forma:

app.get("/users", (req, res) => {
  res.send("Lista de usuarios");
});

Si observas el código, ten en cuenta que estamos ejecutando el método app.get(). Utilizamos get porque estamos realizando una petición GET, sin embargo, existen otros verbos que podemos utilizar (siempre con el método en minúsculas):

Método HTTP Descripción Ejemplo
GET Envía una petición para obtener datos. app.get(...)
POST Envía una petición con el objetivo de crear datos. app.post(...)
PUT Envía una petición con el objetivo de actualizar datos. app.put(...)
DELETE Envía una petición que borrará datos. app.delete(...)

Dependiendo del objetivo de nuestra petición deberíamos utilizar uno u otro.

Rutas dinámicas

En nuestro ejemplo anterior, la ruta o endpoint /users nos mostraría una lista de usuarios. Sin embargo, si quisieramos agregar más endpoints para cada uno de los usuarios, tendríamos que ir añadiendo nuevos endpoints manualmente, y esto no es algo cómodo si tenemos muchos.

Para evitar esto, podemos utilizar rutas dinámicas. Las rutas dinámicas nos permiten definir una ruta con parámetros. Por ejemplo:

// Ruta estática
app.get("/users", (req, res) => {
  res.send("Lista de usuarios");
});

// Ruta dinámica
app.get("/api/user/:name", (req, res) => {
  const name = req.params.name;
  res.send(`Usuario: ${name}`);
});

En esta situación, si accedemos a la URL http://localhost:4321/users nos mostraría el texto Lista de usuarios. Pero si accedemos a la URL http://localhost:4321/api/user/ManzDev nos mostraría el texto Usuario: ManzDev. Esto lo hace porque mediante req.params.name estamos accediendo al valor del parámetro :name, que es el nombre que le hemos dado al escribir la URL.

IMPORTANTE: Ten en cuenta que la información que llega a través de los parámetros de req.params viene directamente del usuario y podría ser información maliciosa. Nunca confíes en los datos que provienen del usuario. Más adelante veremos como validarlos para evitar que sean maliciosos.

Ejemplo completo

Vamos a construir un ejemplo completo, donde creamos un servidor que escucha las rutas del navegador y si indicamos una ruta /users o /api/user/:name nos devuelva la lista de usuarios o la información del usuario indicado:

import express from "express";
const app = express();

const PORT = 4321;

// Data
const users = [
  { name: "ManzDev", role: "streamer", likes: ["css", "js", "webcomponents"] },
  { name: "afor_digital", role: "streamer", likes: ["react", "unocss", "tailwind"] },
  { name: "gentleman_programming", role: "streamer", likes: ["angular", "js", "go"] },
  { name: "BlurSoul_", role: "moderator", likes: ["css", "figma", "shaders"] },
  { name: "felixicaza_", role: "moderator", likes: ["css", "astro", "js"] }
];

// User list
app.get("/users", (req, res) => {
  res.header("Content-Type", "text/html");
  res.write("Lista de usuarios:");

  const userList = users.map(user => user.name);
  res.write(userList.join(", "));
});

// User specific
app.get("/api/user/:name", (req, res) => {
  const name = req.params.name;
  const user = users.find(user => user.name === name);

  if (user) {
    res.json(user);
  }
  else {
    res.status(404).send({ error: `No existe el usuario ${name}` });
  }
});

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

Observa que el código empieza a crecer y se vuelve más difícil de leer. Esto puede convertirse en un problema rápidamente, porque a medida que aumentamos la aplicación, tendremos que ir añadiendo nuevas rutas.

Algunas consideraciones del código anterior:

  • 1️⃣ En el futuro, la información de los usuarios debería estar en una base de datos. De momento, la tendremos en un array o un JSON para simplificar.

  • 2️⃣ Observa que tenemos dos endpoints que tienden a crecer y ser difíciles de leer. Sería una buena idea separarlos en archivos diferentes. Es lo que haremos en el próximo artículo.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev