Introducción
Cuando comencé a desarrollar backend, empecé a construir endpoints REST sin entender realmente cómo funcionaba HTTP (abre en una pestaña nueva) . Con el tiempo me di cuenta de que me había saltado una parte bastante importante.
Además, el framework con el que trabajo trae embebido su propio servidor, y eso me confundía todavía más: no entendía cómo era posible que mis endpoints “levantaran” sin necesidad de desplegarlos en un servidor aparte. Estaba acostumbrado a trabajar con un servidor de aplicaciones (abre en una pestaña nueva) independiente, donde subías el proyecto ya empaquetado. Cambiar esa lógica me costó bastante.
Usaba POST y GET como si fueran comandos mágicos, copiaba respuestas sin preguntarme qué significaban los códigos, y muchas veces no sabía por qué algo fallaba.
Con el tiempo entendí que mis errores no venían del código en sí, sino de no comprender realmente el trasfondo que conlleva un endpoint REST. HTTP no era un detalle escondido por el framework. Era la base de la comunicación entre el cliente y el servidor.
En este artículo quiero explicarte lo que me habría gustado entender desde el principio, sin llenar cada definición de palabras que después necesitan otra definición.
¿Qué es HTTP y por qué importa en el backend?
HTTP (Hypertext Transfer Protocol) (abre en una pestaña nueva) es un protocolo de comunicación entre un cliente (como tu navegador, Postman o una app móvil) y un servidor. Su principal función es definir cómo deben estructurarse las solicitudes y respuestas para que ambas partes se entiendan.
Características clave:
-
•
Cliente-servidor: Quien inicia la comunicación es el cliente.
-
•
Sin estado (stateless): El servidor no recuerda solicitudes anteriores.
-
•
Basado en texto: Las peticiones/respuestas son legibles y estructuradas.
Verbos HTTP: no todo es POST
HTTP define una serie de métodos —también llamados verbos— que indican la intención del cliente. Acá te muestro los más comunes:
| Método | Propósito | ¿Es idempotente? |
|---|---|---|
| GET | Solicita datos al servidor sin modificar nada. | Sí |
| POST | Envía datos para crear un nuevo recurso en el servidor. | No |
| PUT | Reemplaza por completo un recurso existente con uno nuevo. | Sí |
| PATCH | Modifica parcialmente un recurso existente. | Depende* |
| DELETE | Elimina un recurso identificado por su URL. | Sí |
Un método HTTP se considera idempotente (abre en una pestaña nueva) cuando puede ejecutarse múltiples veces sin cambiar el resultado más allá de la primera ejecución.
Por ejemplo, eliminar el mismo recurso varias veces con DELETE no lo borra más de una vez.
Además de la idempotencia, hay otros aspectos importantes como los métodos safe (seguros, que no modifican nada) o los cacheables (cuyas respuestas pueden almacenarse para futuras solicitudes).
Si querés profundizar más en cada uno —qué hacen, cuáles son seguros, idempotentes o cacheables— te recomiendo esta guía buenísima, clara y en español: Métodos HTTP en MDN (abre en una pestaña nueva)
Ejemplos de uso con la herramienta curl :
Códigos de estado: no todo es 200 OK
Cuando hacés una solicitud HTTP, el servidor siempre devuelve un código de estado HTTP (abre en una pestaña nueva) .
Ese número de tres cifras te dice si todo salió bien, si algo falló, o si el servidor ni siquiera entendió lo que pediste.
Acá te muestro los más comunes, agrupados por categoría:
| Código | Descripción |
|---|---|
| 200 OK | Todo salió bien. Es la respuesta más común cuando todo funciona como se espera. |
| 201 Created | Recurso creado correctamente. Se usa normalmente después de un POST. |
| 204 No Content | La solicitud fue exitosa pero no hay nada que devolver (útil para DELETE). |
| 400 Bad Request | La solicitud estaba mal formada o faltaba algo. Error del cliente. |
| 401 Unauthorized | Faltan credenciales o el token no es válido. |
| 403 Forbidden | Las credenciales están bien, pero no tenés permisos para acceder al recurso. |
| 404 Not Found | El recurso que estás buscando no existe (o la URL está mal escrita). |
| 500 Internal Server Error | Algo falló del lado del servidor. Generalmente es un bug o error inesperado. |
Aunque todos hemos celebrado un 200 OK, la verdad es que no siempre es la respuesta correcta. Usar el código adecuado no solo hace tu API más clara, también le facilita la vida a quien la consume. Por ejemplo, si alguien envía datos incompletos o inválidos, un 400 Bad Request dice mucho más que un 200 fingiendo que todo está bien.
Headers HTTP: la información que acompaña la petición
Los headers o encabezados (abre en una pestaña nueva) son pequeñas piezas de información que acompañan cada solicitud o respuesta HTTP. Aunque a veces pasen desapercibidos, son clave para que el cliente y el servidor se entiendan bien.
Acá te dejo algunos headers comunes que vas a encontrarte muy seguido:
| Header | ¿Para qué sirve? |
|---|---|
| Content-Type | Le dice al servidor el tipo de contenido que está enviando el cliente. Por ejemplo: application/json. |
| Accept | Le indica al servidor qué formato de respuesta espera el cliente (JSON, HTML, etc.). |
| Authorization | Se usa para enviar credenciales o tokens. Por ejemplo: Bearer abc123. |
| User-Agent | Identifica al cliente que hace la solicitud (navegador, app, Postman...). |
| Cache-Control | Controla cómo se almacenan en caché las respuestas. |
Un header mal configurado puede hacer que una API falle o que el servidor no entienda lo que estás enviando.
Por ejemplo, si mandás JSON pero no ponés Content-Type: application/json , el servidor podría ignorar completamente el cuerpo de tu solicitud.
El cuerpo, la URL y los parámetros
Cuando hacés una solicitud HTTP, tenés varias formas de enviar datos.
Cada una tiene su propósito y se usa en contextos diferentes.
| Parte | Ejemplo | ¿Cuándo se usa? |
|---|---|---|
| Path Params | /usuarios/42 | Cuando querés identificar un recurso específico por su ID o nombre. |
| Query Params | /usuarios?activo=true&pagina=2 | Cuando necesitás filtrar, buscar o paginar resultados. |
| Body | { "nombre": "Mario", "email": "mario@email.com" } | Cuando enviás datos estructurados, como al crear o actualizar un recurso. |
Una buena práctica es usar los path params para identificar recursos, los query params para filtros u opciones, y el cuerpo (body) para enviar los datos en sí.
Y algo clave: no todos los métodos permiten body. Por ejemplo, GET no debería usarse con cuerpo, aunque técnicamente algunos clientes lo permitan.
Ejemplo completo: mini API REST
Supongamos que tenés una API de usuarios. Así se vería un flujo básico de operaciones comunes:
Este ejemplo cubre lo básico: creación, lectura, actualización y eliminación de recursos (lo que normalmente se conoce como CRUD).
Si querés practicar este tipo de solicitudes de forma más visual, además de curl o Postman, te recomiendo probar Cartero (abre en una pestaña nueva) , un cliente HTTP de escritorio liviano, creado como proyecto open source.
Conclusión
HTTP no es solo para navegadores: también es el lenguaje de las APIs. Mientras escribía este artículo pensé en lo mucho que me habría servido entender algunas cosas desde el principio: que un GET no debería depender de un body (aunque lo intenté), que los códigos de estado no son decorativos y que los verbos y headers expresan parte del contrato.
Este artículo terminó siendo un poco más largo porque al escribirlo me tocó investigar y repasar varios conceptos. Y si algo puedo recomendarte, es esto: consultá fuentes oficiales. Sitios como MDN (abre en una pestaña nueva) o Cloudflare (abre en una pestaña nueva) son excelentes para aclarar dudas. Porque seamos honestos: no nos vamos a saber todo, y está bien.