REST no es HTTP, pero prácticamente todas las APIs REST del mundo viajan sobre HTTP. Si no entiendes el protocolo, acabarás copiando ejemplos sin saber por qué funcionan y depurando a ciegas cuando dejen de hacerlo. Esta lección abre HTTP en canal: veremos en crudo cómo es una petición y una respuesta, qué implica que el protocolo sea sin estado, cómo se descompone una URL, qué cabeceras aparecen en casi todas las APIs, por qué todo debe ir cifrado y qué cambia entre HTTP/1.1, HTTP/2 y HTTP/3. Terminaremos observando tráfico real contra la API de Tienda Aroma con curl -v y con las herramientas del navegador.
Esta es una lección de mapa y fundamentos: presentaremos los métodos y los códigos de estado como panorámica, pero su estudio detallado corresponde a las lecciones 02-03 y 02-04.
Contenido
- Qué es HTTP y qué papel juega en una API
- Anatomía de una petición HTTP
- Anatomía de una respuesta HTTP
- El modelo petición-respuesta y la ausencia de estado
- La URL y sus partes
- Cabeceras habituales en APIs
- Panorámica de métodos y códigos de estado
- HTTPS y TLS: por qué toda API va cifrada
- HTTP/1.1, HTTP/2 y HTTP/3
- Observar HTTP:
curl -vy las DevTools
- Qué es HTTP y qué papel juega en una API
HTTP (HyperText Transfer Protocol) es un protocolo de la capa de aplicación que define cómo un cliente pide algo a un servidor y cómo este responde. Tres características lo definen:
- Es textual en sus versiones clásicas: se puede leer con los ojos, lo que facilita enormemente depurar.
- Sigue un modelo petición-respuesta: por cada petición hay exactamente una respuesta.
- Es sin estado: el servidor no recuerda nada de peticiones anteriores.
Cuando en la lección 01-01 escribimos curl https://api.tiendaaroma.example/v1/cafes, curl construyó un mensaje HTTP, lo envió por una conexión de red y nos mostró solo el cuerpo de la respuesta. Ahora vamos a ver ese mensaje completo.
sequenceDiagram
participant C as Cliente
participant S as Servidor de Tienda Aroma
Note over C,S: 1. Se establece la conexión (TCP + TLS)
C->>S: Petición: línea de petición + cabeceras + cuerpo
Note over S: 2. El servidor procesa
S-->>C: Respuesta: línea de estado + cabeceras + cuerpo
Note over C,S: 3. La conexión se reutiliza o se cierra
- Anatomía de una petición HTTP
Toda petición HTTP tiene tres partes: línea de petición, cabeceras y, opcionalmente, cuerpo. Así es una petición completa para crear un pedido en Tienda Aroma:
POST /v1/pedidos HTTP/1.1
Host: api.tiendaaroma.example
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
User-Agent: AromaMovil/2.4 (Android 14)
Content-Length: 118
{
"clienteId": "cli_842",
"lineas": [
{ "cafeId": "caf_001", "cantidad": 2 }
]
}Analicemos cada elemento:
Línea de petición (POST /v1/pedidos HTTP/1.1). Tiene exactamente tres piezas separadas por espacios:
| Pieza | Valor | Significado |
|---|---|---|
| Método | POST |
La acción que se quiere realizar (aquí, crear algo) |
| Ruta | /v1/pedidos |
Qué recurso es el destinatario, sin el dominio |
| Versión | HTTP/1.1 |
Qué versión del protocolo habla el cliente |
Cabeceras: pares Nombre: valor, una por línea. Son metadatos sobre la petición: describen el mensaje, no forman parte del dato enviado. Host es obligatoria en HTTP/1.1 porque un mismo servidor puede alojar muchos dominios y necesita saber a cuál va dirigida.
Línea en blanco: separa las cabeceras del cuerpo. Es obligatoria, y es la marca que le dice al servidor "las cabeceras han terminado".
Cuerpo (body): los datos que se envían. Aquí, el pedido en JSON. Las peticiones GET normalmente no llevan cuerpo; las de creación o modificación sí.
Punto clave: la ruta va sin dominio en la línea de petición. El dominio viaja en la cabecera
Host. Al escribirhttps://api.tiendaaroma.example/v1/pedidos, el cliente descompone esa dirección en las dos partes automáticamente.
- Anatomía de una respuesta HTTP
La respuesta tiene la misma estructura, cambiando la primera línea:
HTTP/1.1 201 Created
Date: Fri, 14 Aug 2026 09:12:44 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 226
Location: /v1/pedidos/ped_5001
Cache-Control: no-store
{
"id": "ped_5001",
"clienteId": "cli_842",
"estado": "pendiente_pago",
"totalEuros": 29.00,
"lineas": [
{ "cafeId": "caf_001", "nombre": "Etiopía Yirgacheffe", "cantidad": 2, "precioEuros": 14.50 }
]
}Línea de estado (HTTP/1.1 201 Created):
| Pieza | Valor | Significado |
|---|---|---|
| Versión | HTTP/1.1 |
Versión que habla el servidor |
| Código | 201 |
Resultado en forma de número, interpretable por máquinas |
| Frase | Created |
Descripción legible; puramente informativa |
Cabeceras de respuesta: aquí Content-Type indica que el cuerpo es JSON codificado en UTF-8, Content-Length dice cuántos bytes ocupa, Location señala dónde ha quedado el recurso recién creado (una convención muy útil que retomaremos en 02-04) y Cache-Control: no-store prohíbe guardar esta respuesta en caché, cosa razonable en un pedido.
Cuerpo: la representación del recurso creado. Fíjate en que el servidor ha añadido información que el cliente no envió: el id, el estado inicial y el totalEuros calculado. El cliente no calcula precios; eso es lógica de negocio del servidor.
- El modelo petición-respuesta y la ausencia de estado
HTTP funciona por turnos estrictos: el cliente pregunta, el servidor responde. El servidor nunca inicia la conversación (para eso están los webhooks, los Server-Sent Events y los WebSockets, que veremos en 01-07).
La propiedad más importante para nosotros es que HTTP no tiene estado (stateless): cada petición es independiente y el servidor no recuerda nada de las anteriores. Si envías estas dos peticiones seguidas:
curl https://api.tiendaaroma.example/v1/cafes/caf_001
curl https://api.tiendaaroma.example/v1/cafes/caf_002el servidor no sabe que la segunda viene del mismo cliente que la primera, salvo que se lo digas explícitamente en la propia petición.
Consecuencia práctica número uno: cada petición debe llevar toda la información necesaria para ser atendida, incluida la identidad de quien la hace. Por eso la cabecera Authorization se repite en todas y cada una de las peticiones autenticadas, y no "se inicia sesión una vez".
Consecuencia práctica número dos: como ninguna petición depende de una anterior, cualquier servidor de un grupo puede atender cualquier petición. Esto es lo que permite poner diez servidores detrás de un balanceador y escalar horizontalmente.
Cuidado con una confusión frecuente: que el protocolo no tenga estado no significa que no haya datos persistentes. El carrito de Tienda Aroma se guarda en la base de datos y es un recurso más (/v1/carritos/car_77); lo que no existe es una "sesión" viva en la memoria de un servidor concreto. La diferencia entre estado de aplicación y estado de sesión es central en REST y la retomamos en 01-04.
- La URL y sus partes
Una URL identifica de forma única un recurso en la red. Analicemos una completa de Tienda Aroma:
https://api.tiendaaroma.example:443/v1/cafes?origen=Etiopia&tueste=claro#notas \___/ \_______________________/\_/\________/\______________________/ \___/ 1 2 3 4 5 6
| # | Parte | Ejemplo | Para qué sirve |
|---|---|---|---|
| 1 | Esquema | https |
Protocolo a usar. En APIs, siempre https |
| 2 | Host | api.tiendaaroma.example |
Servidor al que conectarse |
| 3 | Puerto | 443 |
Puerto TCP. Se omite si es el estándar (80 para http, 443 para https) |
| 4 | Ruta | /v1/cafes |
Qué recurso se pide dentro de ese servidor |
| 5 | Query string | ?origen=Etiopia&tueste=claro |
Parámetros: filtros, orden, paginación |
| 6 | Fragmento | #notas |
No se envía al servidor; solo lo usa el navegador |
Detalles que conviene interiorizar:
- La query string empieza con
?y encadena paresclave=valorseparados por&. Es el lugar natural para lo que modula la consulta (filtrar, ordenar, paginar), no para identificar el recurso. Lo desarrollaremos en 02-06. - El fragmento nunca llega al servidor. No lo uses jamás para transportar datos de una API.
- Los valores deben ir codificados (percent-encoding) si contienen caracteres especiales: un espacio es
%20, unañse codifica en varios bytes. Por eso escribimosorigen=Etiopiasin tilde en el ejemplo, o bienorigen=Etiop%C3%ADa.
Con curl, conviene entrecomillar la URL para que el shell no interprete el & como "ejecutar en segundo plano":
# Correcto: la URL completa entre comillas
curl "https://api.tiendaaroma.example/v1/cafes?origen=Etiopia&tueste=claro"
# Incorrecto: el shell parte la orden en el & y curl solo recibe hasta "Etiopia"
curl https://api.tiendaaroma.example/v1/cafes?origen=Etiopia&tueste=claroVerás también el término URI. En la práctica de las APIs web, URI y URL se usan como sinónimos; formalmente, URI es el concepto general de identificador y URL es un identificador que además indica cómo localizar el recurso.
- Cabeceras habituales en APIs
Hay decenas de cabeceras estándar. Estas son las que aparecerán una y otra vez en el curso:
| Cabecera | Dirección | Para qué sirve | Ejemplo |
|---|---|---|---|
Content-Type |
Ambas | Formato del cuerpo de este mensaje | application/json; charset=utf-8 |
Accept |
Petición | Formatos que el cliente sabe recibir | application/json |
Authorization |
Petición | Credenciales de quien llama | Bearer eyJhbGci... |
User-Agent |
Petición | Quién es el cliente (nombre y versión) | AromaMovil/2.4 (Android 14) |
Content-Length |
Ambas | Tamaño del cuerpo en bytes | 226 |
Cache-Control |
Ambas | Política de caché | max-age=300, public |
Location |
Respuesta | Dirección de un recurso creado o de redirección | /v1/pedidos/ped_5001 |
Date |
Respuesta | Momento en que se generó la respuesta | Fri, 14 Aug 2026 09:12:44 GMT |
Tres precisiones importantes:
Content-TypeyAcceptno son lo mismo.Content-Typedescribe lo que envío;Acceptdescribe lo que quiero recibir. Una peticiónPOSTsuele llevar las dos: "te mando JSON y quiero JSON de vuelta". UnaGETsolo llevaAccept, porque no envía cuerpo. Este mecanismo se llama negociación de contenido y es materia de 02-05.Authorizationcon esquemaBeareres el patrón dominante hoy: se envía un token que el servidor valida. Toda la mecánica (JWT, OAuth 2.0) se ve en 03-06 y 04-03.- Las cabeceras no distinguen mayúsculas de minúsculas en su nombre (
content-typees igual queContent-Type), aunque por convención se escriben capitalizadas. En HTTP/2 y HTTP/3 viajan siempre en minúsculas.
Existen además cabeceras personalizadas. La convención moderna es no usar el prefijo X- (desaconsejado desde el RFC 6648) y elegir nombres específicos como Aroma-Peticion-Id.
- Panorámica de métodos y códigos de estado
Aquí solo dibujamos el mapa. El estudio detallado de cada método está en la lección 02-03 y el de cada código de estado en la 02-04.
Métodos: el verbo de la petición
El método indica la intención de la petición sobre el recurso:
| Método | Intención | Ejemplo en Tienda Aroma |
|---|---|---|
GET |
Obtener una representación | GET /v1/cafes/caf_001 |
POST |
Crear o procesar algo nuevo | POST /v1/pedidos |
PUT |
Reemplazar por completo | PUT /v1/cafes/caf_001 |
PATCH |
Modificar parcialmente | PATCH /v1/cafes/caf_001 |
DELETE |
Eliminar | DELETE /v1/carritos/car_77 |
HEAD |
Como GET pero solo cabeceras |
Comprobar si algo existe o ha cambiado |
OPTIONS |
Consultar qué se permite | Usado por el navegador en CORS (04-05) |
Dos propiedades que ya conviene tener en el radar, porque explican por qué la elección del método importa:
- Seguro (safe): no modifica nada en el servidor.
GETyHEADlo son. Por eso un buscador puede rastrear enlaces sin miedo. - Idempotente: repetir la misma petición varias veces deja el sistema igual que hacerlo una vez.
GET,PUTyDELETElo son;POSTno. De ahí que reintentar unPOST /v1/pedidostras un fallo de red pueda generar dos pedidos, un problema real que abordaremos.
Códigos de estado: el resultado en tres cifras
El primer dígito determina la familia, y con eso ya sabes lo esencial:
| Familia | Significado | Ejemplos frecuentes |
|---|---|---|
| 1xx | Informativo (raro en APIs) | 100 Continue |
| 2xx | Éxito | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirección o "usa tu caché" | 301 Moved Permanently, 304 Not Modified |
| 4xx | Error del cliente: la petición está mal | 400 Bad Request, 401 Unauthorized, 404 Not Found, 422 Unprocessable Content |
| 5xx | Error del servidor: la petición era válida | 500 Internal Server Error, 503 Service Unavailable |
La distinción entre 4xx y 5xx es de las más útiles que existen al depurar: 4xx significa "arregla la petición", 5xx significa "el problema es mío". Un servidor que devuelve 200 OK con un cuerpo {"error": "no encontrado"} está mintiendo al protocolo y rompiendo todo el instrumental automático que se apoya en el código: cachés, reintentos, monitorización y alertas.
- HTTPS y TLS: por qué toda API va cifrada
HTTPS es HTTP transportado dentro de una conexión cifrada con TLS (Transport Layer Security, el sucesor de SSL). Aporta tres garantías:
- Confidencialidad: nadie en el camino puede leer el contenido. Sin TLS, la cabecera
Authorizationcon el token viaja en texto plano y cualquiera en la misma red wifi puede copiarla. - Integridad: nadie puede alterar los mensajes sin que se detecte.
- Autenticidad: el certificado del servidor demuestra que hablas con
api.tiendaaroma.exampley no con un impostor.
En la práctica esto significa:
- Nunca publiques una API por
http://. Ni siquiera "solo para pruebas": las URLs de pruebas acaban en producción. - Redirige el tráfico
httpahttpscon301, pero no confíes en eso como seguridad: la primera petición ya viajó en claro. - Los tokens y claves de API solo son seguros si el canal lo es.
- La API interna también va cifrada. La red interna no es un lugar de confianza; el modelo de confianza cero asume que un atacante ya está dentro.
Verificar el certificado de una API con curl:
Ampliaremos todo esto en la lección 04-02, dedicada a seguridad.
- HTTP/1.1, HTTP/2 y HTTP/3
El modelo conceptual (petición, respuesta, métodos, cabeceras, códigos) es idéntico en las tres versiones. Lo que cambia es cómo se transportan los mensajes:
| Aspecto | HTTP/1.1 (1997) | HTTP/2 (2015) | HTTP/3 (2022) |
|---|---|---|---|
| Formato | Texto | Binario | Binario |
| Transporte | TCP | TCP | QUIC sobre UDP |
| Peticiones simultáneas | Una por conexión (en la práctica, varias conexiones) | Multiplexadas en una conexión | Multiplexadas, sin bloqueo por pérdida |
| Cabeceras | Texto repetido en cada petición | Comprimidas (HPACK) | Comprimidas (QPACK) |
| Problema principal que resuelve | — | Bloqueo de cabecera de línea en HTTP | Bloqueo de cabecera de línea en TCP |
Qué cambia en la práctica para quien diseña una API:
- No cambia tu código. Una API REST funciona igual en las tres versiones; normalmente es el servidor web o el gateway quien decide la versión, y el cliente negocia la mejor disponible.
- Sí cambia el coste de hacer muchas peticiones. Con HTTP/1.1, hacer 30 llamadas para pintar una pantalla era carísimo, y eso empujó a diseñar respuestas grandes que lo devuelven todo. Con HTTP/2 varias peticiones pequeñas son mucho más asumibles. Es un argumento que aparecerá cuando discutamos GraphQL en 01-07.
- Cabeceras baratas: con compresión, repetir
Authorizationen cada petición pesa poco. - HTTP/2 y HTTP/3 exigen TLS en la práctica (todos los navegadores lo requieren), lo que refuerza el punto anterior.
- gRPC se apoya en HTTP/2 precisamente por el multiplexado y el streaming bidireccional.
- Observar HTTP:
curl -v y las DevTools
curl -v y las DevToolsNo se puede aprender HTTP sin verlo. Dos herramientas bastan para el 95 % de los casos.
curl -v
La opción -v (verbose) muestra la conversación completa. Las líneas que empiezan por > son lo que envía el cliente; las que empiezan por <, lo que devuelve el servidor; las que empiezan por * son información de la conexión.
Salida (abreviada y comentada):
* Connected to api.tiendaaroma.example (203.0.113.42) port 443
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256
> GET /v1/cafes/caf_001 HTTP/2
> Host: api.tiendaaroma.example
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/2 200
< content-type: application/json; charset=utf-8
< cache-control: public, max-age=300
< etag: "a7f3c9"
<
{"id":"caf_001","nombre":"Etiopía Yirgacheffe","precioEuros":14.50,"stock":120}Qué nos enseña esta salida:
curlañadió automáticamenteHost,User-AgentyAccept: */*("acepto cualquier formato").- La conexión negoció HTTP/2 y TLS 1.3, y las cabeceras de respuesta llegan en minúsculas, como corresponde a HTTP/2.
- El servidor permite cachear 5 minutos (
max-age=300) y envía unETag, una huella del contenido que permite revalidar sin descargarlo de nuevo (lección 04-06).
Opciones de curl que usaremos durante todo el curso:
# -i muestra las cabeceras de respuesta junto al cuerpo (más limpio que -v)
curl -i https://api.tiendaaroma.example/v1/cafes/caf_001
# -X fuerza el método, -H añade cabeceras, -d envía cuerpo
curl -X POST https://api.tiendaaroma.example/v1/pedidos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_TOKEN" \
-d '{"clienteId":"cli_842","lineas":[{"cafeId":"caf_001","cantidad":2}]}'
# -I hace una petición HEAD: solo cabeceras, sin descargar el cuerpo
curl -I https://api.tiendaaroma.example/v1/cafes
# -o guarda en fichero y -s silencia la barra de progreso
curl -s https://api.tiendaaroma.example/v1/cafes -o cafes.jsonUn detalle útil: al usar -d, curl ya asume POST y Content-Type: application/x-www-form-urlencoded, por lo que la cabecera Content-Type: application/json es obligatoria si envías JSON. Olvidarla es una de las causas más frecuentes de recibir un 400 desconcertante.
DevTools del navegador
Pulsa F12 en tu navegador y abre la pestaña Red (Network). Con ella puedes:
- Filtrar por Fetch/XHR para ver solo las llamadas a APIs que hace la página, ignorando imágenes y estilos.
- Pinchar una petición y revisar sus pestañas: Headers (línea de petición, código de estado y todas las cabeceras), Payload (el cuerpo enviado), Response (el cuerpo recibido) y Timing (dónde se fue el tiempo).
- Usar Copiar como cURL en el menú contextual: convierte cualquier petición del navegador en una orden
curlreproducible en el terminal. Es la técnica más rápida para depurar una llamada que falla en la web de Tienda Aroma.
Un ejercicio muy formativo: abre cualquier tienda en línea real, filtra por Fetch/XHR y observa las llamadas que hace al añadir algo al carrito. Verás en vivo métodos, rutas, códigos de estado y cuerpos JSON.
Errores Comunes y Consejos
- Enviar JSON sin
Content-Type: application/json. El servidor no adivina el formato; lo tratará como texto o como formulario y fallará al interpretarlo. - Confundir
AcceptconContent-Type. Regla mnemotécnica: Content-Type describe lo que va en este sobre; Accept describe lo que quiero de vuelta. - Poner datos sensibles en la query string. Las URLs quedan registradas en los logs del servidor, en los proxys y en el historial. Los tokens y contraseñas van en cabeceras o en el cuerpo, nunca en la URL.
- Olvidar entrecomillar la URL en
curlcuando lleva&. El shell la parte y recibes resultados incoherentes. - Suponer que el servidor "recuerda" la petición anterior. Sin estado significa exactamente eso: cada petición debe ser autosuficiente.
- Devolver
200 OKpara los errores. Rompe cachés, reintentos automáticos y monitorización. - Preocuparse por HTTP/2 o HTTP/3 en el código de la API. Es una decisión de infraestructura; tu trabajo es diseñar bien el contrato.
- Consejo: dedica quince minutos a lanzar
curl -vcontra tres o cuatro APIs públicas que uses. Ver cabeceras reales de servicios reales enseña más que cualquier tabla.
Ejercicios
Ejercicio 1: leer una petición en crudo
Dada esta petición, responde: (a) ¿qué método y ruta usa?; (b) ¿a qué dominio va dirigida?; (c) ¿qué formato envía y cuál espera recibir?; (d) ¿lleva credenciales?; (e) ¿qué está haciendo exactamente?
PATCH /v1/cafes/caf_002 HTTP/1.1
Host: api.tiendaaroma.example
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
{ "precioEuros": 13.50 }Ejercicio 2: descomponer una URL
Descompón esta URL en sus seis partes e indica cuál de ellas no llega al servidor. Explica además si ?tueste=claro&limite=10 identifica un recurso distinto o modula una consulta.
Ejercicio 3: construir peticiones con curl
Escribe las órdenes curl para:
- Obtener el café
caf_001mostrando las cabeceras de respuesta. - Comprobar si existe el recurso
/v1/cafes/caf_999sin descargar el cuerpo. - Crear una reseña con
POST /v1/resenasenviando{"cafeId":"caf_001","puntuacion":5,"comentario":"Excelente"}autenticado con el tokenTOKEN123. - Pedir los cafés de Etiopía con tueste claro, con la URL correctamente entrecomillada.
Soluciones
Solución 1
- (a) Método
PATCHsobre la ruta/v1/cafes/caf_002. - (b) A
api.tiendaaroma.example, indicado en la cabeceraHost(la línea de petición nunca lleva el dominio). - (c) Envía
application/json(Content-Type) y espera recibirapplication/json(Accept). - (d) Sí:
Authorization: Bearer ...con un token. - (e) Modifica parcialmente el café
caf_002, cambiando solo su precio a 13,50 €. Al serPATCHy noPUT, el resto de campos (nombre,origen,stock) se conservan. Es una operación típica del panel interno, y por eso requiere autenticación.
Solución 2
| Parte | Valor |
|---|---|
| Esquema | https |
| Host | api.tiendaaroma.example |
| Puerto | No indicado; se asume 443 por ser https |
| Ruta | /v1/cafes |
| Query string | ?tueste=claro&limite=10 |
| Fragmento | #resultados |
La parte que no llega al servidor es el fragmento #resultados: el navegador lo usa localmente y jamás lo envía.
La query string modula la consulta: el recurso sigue siendo la colección de cafés (/v1/cafes), pero pedimos un subconjunto filtrado y limitado. No es un recurso distinto; es la misma colección vista con otros criterios. Por eso los filtros van en la query string y no en la ruta.
Solución 3
# 1. Obtener un café mostrando cabeceras de respuesta
curl -i https://api.tiendaaroma.example/v1/cafes/caf_001
# 2. Comprobar existencia sin descargar el cuerpo (petición HEAD)
curl -I https://api.tiendaaroma.example/v1/cafes/caf_999
# Devolvería 404 Not Found en la línea de estado, sin cuerpo
# 3. Crear una reseña autenticada
curl -X POST https://api.tiendaaroma.example/v1/resenas \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN123" \
-d '{"cafeId":"caf_001","puntuacion":5,"comentario":"Excelente"}'
# 4. Filtrar cafés (URL entrecomillada por el &)
curl "https://api.tiendaaroma.example/v1/cafes?origen=Etiopia&tueste=claro"Errores frecuentes en este ejercicio: olvidar Content-Type en el punto 3 (el servidor no interpretaría el JSON), usar -X GET con -I (son incompatibles: -I ya implica HEAD) y no entrecomillar la URL del punto 4.
Conclusión
HTTP es el terreno sobre el que se construye todo lo demás. Ya sabes leer una petición y una respuesta en crudo, distinguir sus tres partes, descomponer una URL y reconocer las cabeceras que aparecerán en cada lección del curso. Has visto que la ausencia de estado obliga a que cada petición sea autosuficiente —y a la vez es lo que permite escalar—, que las familias de códigos separan claramente la culpa entre cliente y servidor, que HTTPS no es opcional y que las versiones del protocolo cambian el transporte pero no el modelo. Y, sobre todo, ya tienes dos herramientas, curl -v y las DevTools, para observar lo que ocurre de verdad en lugar de suponerlo.
Con este material podemos abordar la pregunta central del módulo. En la siguiente lección, Principios básicos de REST, veremos cómo Roy Fielding convirtió las propiedades de la web en seis restricciones arquitectónicas, qué son exactamente un recurso, un identificador y una representación, y por qué muchas APIs que se anuncian como REST no lo son del todo.
Curso de REST API: Principios de Diseño y Desarrollo de APIs RESTful
Módulo 1: Introducción a las APIs RESTful
- ¿Qué es una API?
- Historia y evolución de las APIs
- Fundamentos de HTTP para APIs
- Principios básicos de REST
- Modelo de madurez de Richardson y HATEOAS
- REST vs. SOAP
- REST frente a GraphQL, gRPC y webhooks
Módulo 2: Diseño de APIs RESTful
- Principios de diseño de APIs RESTful
- Recursos y URIs
- Métodos HTTP
- Códigos de estado HTTP
- Representaciones, cabeceras y negociación de contenido
- Filtrado, ordenación, paginación y búsqueda
- Versionado de APIs
- Documentación de APIs
Módulo 3: Desarrollo de APIs RESTful
- Configuración del entorno de desarrollo
- Creación de un servidor básico
- Manejo de peticiones y respuestas
- Validación de datos de entrada
- Persistencia y capa de acceso a datos
- Autenticación y autorización
- Manejo de errores
- Pruebas y validación
Módulo 4: Buenas Prácticas y Seguridad
- Buenas prácticas en el diseño de APIs
- Seguridad en APIs RESTful
- OAuth 2.0 y OpenID Connect en la práctica
- Rate limiting y throttling
- CORS y políticas de seguridad
- Caché HTTP y rendimiento
- Observabilidad: logs, métricas y trazas
Módulo 5: Herramientas y Frameworks
- Postman para pruebas de APIs
- Swagger y OpenAPI para documentación
- Frameworks populares para APIs RESTful
- Contratos, mocks y pruebas automatizadas de API
- Integración continua y despliegue
- API gateways y portales de desarrollador
