Casi cualquier aplicación moderna habla con un servidor en algún momento: para guardar datos, para mostrar información actualizada, para autenticar a un usuario. Esa comunicación casi siempre pasa por una API REST. Entender cómo funciona no es opcional si vas a trabajar con desarrollo web, sea frontend o backend.

REST son las siglas de Representational State Transfer, un estilo arquitectónico para diseñar APIs sobre HTTP — no un protocolo que se instala ni una tecnología concreta que se aprende, sino un conjunto de convenciones: cada "recurso" (un usuario, un pedido, un producto) tiene una URL propia, y las acciones sobre ese recurso se expresan con verbos HTTP en lugar de con nombres de función.

La idea central: recursos y verbos

En vez de tener una URL distinta para cada acción posible (/obtenerUsuario, /borrarUsuario, /actualizarUsuario), REST usa la misma URL de recurso y cambia el verbo HTTP según lo que quieras hacer:

VerboAcciónEjemplo
GETLeer un recurso o una listaGET /usuarios/3
POSTCrear un recurso nuevoPOST /usuarios
PUTReemplazar un recurso enteroPUT /usuarios/3
PATCHModificar parte de un recursoPATCH /usuarios/3
DELETEEliminar un recursoDELETE /usuarios/3

Es la misma lógica que aplicarías montando tu propio servidor con Node.js y Express: cada ruta define un recurso, y el verbo determina qué controlador se ejecuta.

Códigos de estado: lo que la respuesta te está diciendo

Cada respuesta HTTP incluye un código numérico que resume qué pasó. Aprender a leerlos te ahorra tiempo depurando: el código ya te dice si el problema está en tu petición o en el servidor.

CódigoSignificadoCuándo aparece
200 OKÉxitoLa petición se procesó correctamente
201 CreatedRecurso creadoDespués de un POST exitoso
400 Bad RequestPetición mal formadaFalta un campo o el formato es incorrecto
401 UnauthorizedNo autenticadoFalta o es inválido el token de acceso
403 ForbiddenSin permisosAutenticado, pero sin acceso a ese recurso
404 Not FoundNo existeEl recurso solicitado no está en el servidor
500 Internal Server ErrorError del servidorAlgo falló en el backend, no en tu petición

Confundir un 401 con un 403, o un error de red con un 500, es de los fallos más comunes al depurar una integración. Merece la pena tenerlos claros, sobre todo porque muchos de los fallos de seguridad del OWASP Top 10 giran precisamente en torno a devolver el código de acceso equivocado en el momento equivocado.

Consumiendo una API real con fetch

La forma más directa de hacer peticiones HTTP desde JavaScript, sin instalar nada, es con fetch. A continuación tienes dos ejemplos reales contra JSONPlaceholder, una API pública gratuita pensada exactamente para practicar este tipo de peticiones.

javascript
async function obtenerPost(id) {
  const respuesta = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);

  if (!respuesta.ok) {
    throw new Error(`Error ${respuesta.status}: no se pudo obtener el post`);
  }

  const post = await respuesta.json();
  return post;
}

obtenerPost(1).then(post => console.log(post.title));
// "sunt aut facere repellat provident occaecati excepturi optio"
javascript
async function crearPost(titulo, cuerpo, usuarioId) {
  const respuesta = await fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      title: titulo,
      body: cuerpo,
      userId: usuarioId
    })
  });

  if (!respuesta.ok) {
    throw new Error(`Error ${respuesta.status}: no se pudo crear el post`);
  }

  return respuesta.json(); // incluye el id asignado por el servidor
}

crearPost('Mi primer post', 'Contenido de prueba', 1)
  .then(nuevo => console.log(nuevo.id)); // 101

Fíjate en dos detalles que se repiten en casi cualquier petición real: el GET no necesita más que la URL, mientras que el POST necesita indicar la cabecera Content-Type: application/json y convertir el objeto a texto con JSON.stringify antes de enviarlo. Olvidar cualquiera de los dos es la causa número uno de un POST que "no hace nada" sin dar ningún error visible.

Manejo de errores: no confíes solo en el try/catch

Un error habitual es pensar que fetch lanza una excepción cuando la respuesta es un error HTTP. No es así: fetch solo rechaza la promesa si hay un fallo de red (sin conexión, dominio inexistente). Un 404 o un 500 llegan como una respuesta "normal", y por eso siempre hay que comprobar respuesta.ok explícitamente, como en los ejemplos anteriores, antes de asumir que todo fue bien.

Autenticación básica en APIs REST

Muchas APIs reales no son públicas como JSONPlaceholder: requieren identificarte en cada petición, normalmente con un token en la cabecera Authorization.

javascript
const respuesta = await fetch('https://api.ejemplo.com/perfil', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

Ese token nunca debería quedar visible en el código fuente del frontend ni subirse a un repositorio público: es una de las formas más comunes de sufrir un problema de configuración de seguridad incorrecta. Si necesitas construir tu propia API para que otras aplicaciones la consuman así, Express es un buen punto de partida por lo directo que resulta definir rutas y middlewares de autenticación.

REST no es la única opción, pero sigue siendo la más común

Existen alternativas como GraphQL o gRPC, más adecuadas para casos concretos (consultas muy flexibles, comunicación entre microservicios de alto rendimiento). Pero REST sigue siendo el estándar de facto para APIs públicas y para la comunicación típica entre frontend y backend, precisamente porque es simple, se apoya en HTTP tal cual y cualquier cliente —desde un navegador hasta un script de terminal— puede consumirla sin dependencias especiales.

JR

Javier Rodríguez Fernández

Programador con Grado Superior en Desarrollo de Aplicaciones Multiplataforma (DAM). Escribe en DevPulso sobre programación aplicada, sin relleno.