Aprender / Hoja de referencia
Hoja de referencia de HTTP para testing de APIs
Lo que un tester necesita de HTTP en una sola hoja: qué métodos son seguros e idempotentes, qué código de estado debe devolver cada situación, las cabeceras que vale la pena comprobar, los flags de cURL que usarás a diario y un checklist para cada respuesta.
Revisada con Semántica HTTP según RFC 9110; Problem Details según RFC 9457
Métodos
| Método | Uso | Seguro | Idempotente |
|---|---|---|---|
GET | Leer un recurso o una colección | Sí | Sí |
HEAD | Como GET, solo cabeceras | Sí | Sí |
OPTIONS | Métodos permitidos; preflight de CORS | Sí | Sí |
POST | Crear, o ejecutar una acción | No | No |
PUT | Reemplazar el recurso completo | No | Sí |
PATCH | Cambiar algunos campos | No | No garantizado |
DELETE | Eliminar un recurso | No | Sí |
Idempotente significa que repetir la petición deja el servidor en el mismo estado. La respuesta puede variar: un segundo DELETE puede devolver 404.
Códigos de estado que hay que comprobar
| Código | Significado | Prueba típica |
|---|---|---|
200 OK | Éxito con cuerpo | GET de un recurso existente |
201 Created | Recurso creado | POST con datos válidos; comprobar la cabecera Location |
204 No Content | Éxito, cuerpo vacío | DELETE, o un PUT que no devuelve nada |
301 / 308 | Movido permanentemente | La URL antigua redirige; 308 conserva el método |
304 Not Modified | La copia en caché sigue siendo válida | GET con If-None-Match: <etag> |
400 Bad Request | Petición mal formada | JSON inválido, tipos incorrectos |
401 Unauthorized | No autenticado | Token ausente o caducado |
403 Forbidden | Autenticado, sin permiso | Acceder al recurso de otro usuario |
404 Not Found | No existe el recurso | Id desconocido (u ocultar uno que no puedes ver) |
405 Method Not Allowed | Método incorrecto para esta URL | DELETE sobre un endpoint de solo lectura |
409 Conflict | Choca con el estado actual | Email duplicado, versión obsoleta |
415 Unsupported Media Type | Formato de cuerpo no aceptado | Enviar text/plain a un endpoint JSON |
422 Unprocessable Content | JSON válido, valores inválidos | Errores de validación de reglas de negocio |
429 Too Many Requests | Límite de peticiones alcanzado | Ráfaga de peticiones; comprobar Retry-After |
500 Internal Server Error | Bug del servidor | Nunca esperado: siempre es un defecto |
502 / 503 / 504 | Fallo upstream, no disponible, timeout | Dependencia caída; comprobar los reintentos |
Cabeceras que vale la pena comprobar
| Cabecera | Ejemplo | Por qué |
|---|---|---|
Content-Type | application/json; charset=utf-8 | El formato de la respuesta coincide con el cuerpo |
Accept | application/json | El cliente pide un formato; espera 406 si no se admite |
Authorization | Bearer eyJhbGciOi… | Autenticación por token; si falta → 401 |
Location | /api/orders/1043 | Se envía con 201 Created y en las redirecciones |
Cache-Control | no-store | Los datos personales o sensibles no deben guardarse en caché |
ETag / If-None-Match | "a1b2c3" | GET condicional → 304 |
Retry-After | 30 | Se envía con 429 o 503 |
Set-Cookie | sid=…; HttpOnly; Secure; SameSite=Lax | Las cookies de sesión necesitan HttpOnly y Secure |
Access-Control-Allow-Origin | https://app.example.com | CORS: nunca * en peticiones con credenciales |
cURL
| Tarea | Código |
|---|---|
| Mostrar estado y cabeceras | curl -i https://api.example.com/users/1 |
| Traza completa de petición y respuesta | curl -v https://api.example.com/users/1 |
| POST con JSON | curl -X POST https://api.example.com/users \
-H 'Content-Type: application/json' \
-d '{"email":"qa@example.com"}' |
| Bearer token | curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me |
| Basic auth | curl -u user:pass https://api.example.com/admin |
| Seguir redirecciones | curl -L https://example.com/old |
| Solo el código de estado | curl -s -o /dev/null -w '%{http_code}' https://api.example.com/health |
| Fallar con 4xx/5xx en scripts | curl --fail-with-body https://api.example.com/health |
En el cmd de Windows, cambia las comillas simples por dobles y escapa las interiores.
Checklist para cada respuesta
| Comprobación | Ejemplo |
|---|---|
| Código de estado | Exactamente 201, no "cualquier 2xx" |
| Esquema del cuerpo | Campos obligatorios presentes, tipos correctos, sin campos sensibles de más |
| Valores | Los datos enviados vuelven igual; los campos calculados (totales, fechas) son correctos |
| Cabeceras | Content-Type, Location, Cache-Control |
| Forma del error | Formato de error consistente (p. ej., problem details de RFC 9457) con un mensaje útil |
| Efectos secundarios | El registro existe, o no, cuando haces GET de nuevo |
| Tiempo de respuesta | Dentro del presupuesto acordado |