← Node & Express

APIs REST

¿Qué es una API REST y cuáles son sus principios fundamentales?

Ver respuesta — intenta responderla en voz alta primero

REST es un estilo de arquitectura para diseñar APIs sobre HTTP. Sus ideas centrales son: exponer recursos identificados por URLs (usando sustantivos, no verbos), operar sobre ellos con los verbos HTTP (GET, POST, PUT, PATCH, DELETE), ser stateless (cada petición lleva toda la información necesaria) y usar representaciones de los recursos, normalmente en JSON.

REST (Representational State Transfer) es una forma de organizar cómo el cliente y el servidor se comunican. En lugar de inventar nombres para cada acción, seguimos convenciones claras:

  • Recursos identificados por URLs. Un recurso es una "cosa" de tu sistema: un usuario, un producto, un pedido. Cada recurso tiene una URL que lo identifica. La URL usa sustantivos, no verbos. La acción la indica el verbo HTTP, no la URL.
    • Correcto: GET /usuarios, GET /usuarios/42
    • Incorrecto: GET /getUsuarios, POST /crearUsuario
  • Verbos HTTP para las acciones. El mismo recurso /usuarios/42 cambia de comportamiento según el verbo: GET lo lee, PUT lo reemplaza, DELETE lo borra.
  • Stateless (sin estado). El servidor no guarda sesión entre peticiones. Cada petición debe traer todo lo necesario para entenderse por sí sola (por ejemplo, un token de autenticación en las cabeceras). Esto hace que la API escale mejor: cualquier servidor puede atender cualquier petición.
  • Representaciones. El cliente no recibe el objeto interno del servidor, sino una representación de ese recurso. Lo más común es JSON. El mismo recurso podría representarse en distintos formatos, pero JSON es el estándar de facto.

En resumen: URLs de sustantivos + verbos HTTP + sin estado + JSON.

const express = require('express');
const app = express();

// Middleware para que Express entienda cuerpos JSON en las peticiones
app.use(express.json());

// "Base de datos" en memoria solo para el ejemplo
let usuarios = [
  { id: 1, nombre: 'Ana' },
  { id: 2, nombre: 'Luis' },
];

// Recurso: /usuarios (sustantivo en plural, NO /getUsuarios)

// GET /usuarios -> lee la colección completa
app.get('/usuarios', (req, res) => {
  res.json(usuarios); // Devuelve una representación JSON
});

// GET /usuarios/:id -> lee un recurso concreto
app.get('/usuarios/:id', (req, res) => {
  const id = Number(req.params.id);
  const usuario = usuarios.find((u) => u.id === id);

  if (!usuario) {
    return res.status(404).json({ error: 'Usuario no encontrado' });
  }
  res.json(usuario);
});

// POST /usuarios -> crea un nuevo recurso en la colección
app.post('/usuarios', (req, res) => {
  const nuevo = { id: usuarios.length + 1, nombre: req.body.nombre };
  usuarios.push(nuevo);
  res.status(201).json(nuevo); // 201 = creado
});

app.listen(3000, () => console.log('API escuchando en el puerto 3000'));

Probando la API con curl:

# Leer todos los usuarios
curl http://localhost:3000/usuarios

# Leer un usuario concreto
curl http://localhost:3000/usuarios/1

# Crear un usuario nuevo
curl -X POST http://localhost:3000/usuarios \
  -H "Content-Type: application/json" \
  -d '{"nombre":"Marta"}'

Poner verbos en la URL en lugar de sustantivos: POST /crearUsuario, GET /obtenerUsuarios, POST /borrarUsuario/5. Esto rompe la idea de REST, porque el verbo ya lo aporta el método HTTP. La URL debe nombrar el recurso (/usuarios), y el método HTTP indica qué haces con él.

Otro error frecuente es asumir que el servidor "recuerda" al cliente entre peticiones (guardar en memoria del servidor quién está logueado). REST es stateless: cada petición debe incluir por sí misma lo que necesita, como el token de autenticación.

"REST es un estilo de arquitectura para APIs sobre HTTP. La idea central es que expongo recursos identificados por URLs, y esas URLs usan sustantivos, no verbos: por ejemplo /usuarios, no /getUsuarios. La acción la determina el verbo HTTP: GET para leer, POST para crear, PUT o PATCH para actualizar y DELETE para borrar. Otro principio clave es que es stateless: el servidor no guarda sesión entre peticiones, así que cada petición lleva toda la información que necesita, como el token de autenticación en las cabeceras. Y el cliente trabaja con representaciones del recurso, que normalmente son JSON. Siguiendo estas convenciones la API queda predecible y fácil de consumir."

Reto rápido

Tienes una API que gestiona "productos". Un compañero definió estos endpoints:

¿Cómo los reescribirías siguiendo los principios REST?

Ver respuesta

Usando un sustantivo para el recurso (/productos) y dejando que el verbo HTTP indique la acción:

  • GET /obtenerProductos -> GET /productos
  • POST /nuevoProducto -> POST /productos
  • POST /eliminarProducto/10 -> DELETE /productos/10

La URL nombra el recurso; el método HTTP dice qué hacer con él.