métodos HTTP
Métodos HTTP - Guía Completa
Los métodos HTTP (también llamados "verbos HTTP") definen la acción que se quiere realizar sobre un recurso identificado por una URL.
📋 Métodos Principales (CRUD)
1. GET - Leer/Recuperar
Propósito: Solicitar datos de un recurso específico
GET /api/users/123 HTTP/1.1
Host: api.ejemplo.com
Accept: application/jsonCaracterísticas:
Idempotente: Misma petición = misma respuesta
Seguro: No modifica recursos
Cacheable: Se puede almacenar en caché
Sin Body: Generalmente no lleva cuerpo
Códigos de respuesta comunes:
200 OK- Éxito404 Not Found- Recurso no existe304 Not Modified- Usar caché
Ejemplos reales:
# Obtener todos los usuarios
GET /api/users
# Obtener usuario específico
GET /api/users/123
# Con query parameters
GET /api/products?category=electronics&page=2&limit=10
# Con headers específicos
GET /api/data
Accept: application/json
If-None-Match: "etag123"2. POST - Crear
Propósito: Enviar datos para crear un nuevo recurso
POST /api/users HTTP/1.1
Content-Type: application/json
{
"name": "Ana García",
"email": "ana@email.com"
}Características:
No idempotente: Cada POST crea nuevo recurso
No seguro: Modifica el servidor
Con Body: Siempre lleva datos
No cacheable: Por defecto no se cachea
Códigos de respuesta comunes:
201 Created- Recurso creado exitosamente400 Bad Request- Datos inválidos409 Conflict- Recurso ya existe
Headers importantes:
Location: /api/users/456 # URL del nuevo recursoEjemplos reales:
# Crear usuario
POST /api/users
{
"username": "nuevo_user",
"password": "secret"
}
# Crear con archivos (multipart)
POST /api/upload
Content-Type: multipart/form-data
# Procesar datos (aunque no cree recurso)
POST /api/convert
{
"format": "pdf",
"content": "..."
}3. PUT - Reemplazar/Actualizar completo
Propósito: Reemplazar completamente un recurso existente
PUT /api/users/123 HTTP/1.1
Content-Type: application/json
{
"name": "Carlos Actualizado",
"email": "carlos.nuevo@email.com",
"age": 30
}Características:
Idempotente: Mismo PUT = mismo resultado
No seguro: Modifica recursos
Con Body: Lleva todos los datos del recurso
Crear o actualizar: Puede crear si no existe
Ejemplo - Actualizar usuario:
# Antes: {id: 123, name: "Carlos", email: "old@email.com", age: 25}
PUT /api/users/123
{
"name": "Carlos Nuevo",
"email": "new@email.com",
"age": 30
# Nota: Se deben enviar TODOS los campos
}
# Después: {id: 123, name: "Carlos Nuevo", email: "new@email.com", age: 30}4. PATCH - Actualizar parcialmente
Propósito: Modificar parcialmente un recurso
PATCH /api/users/123 HTTP/1.1
Content-Type: application/json
{
"email": "nuevo.email@dominio.com"
}Diferencia clave vs PUT:
// Usuario original
{
id: 123,
name: "Ana",
email: "ana@old.com",
age: 28,
role: "user"
}
// PUT: Debo enviar TODO el objeto
PUT /api/users/123
{
name: "Ana",
email: "ana@new.com", // Solo cambio email
age: 28,
role: "user"
}
// PATCH: Solo envío lo que cambio
PATCH /api/users/123
{
"email": "ana@new.com"
}Formatos comunes para PATCH:
// JSON Patch (RFC 6902)
[
{ "op": "replace", "path": "/email", "value": "new@email.com" },
{ "op": "add", "path": "/phone", "value": "+123456789" }
]
// JSON Merge Patch (RFC 7396)
{
"email": "new@email.com",
"phone": "+123456789"
}
// Simple update
{
"field": "new value"
}5. DELETE - Eliminar
Propósito: Eliminar un recurso específico
DELETE /api/users/123 HTTP/1.1
Authorization: Bearer token123Características:
Idempotente: Eliminar ya eliminado = mismo resultado
No seguro: Modifica el servidor
Sin Body: Generalmente sin cuerpo
Cacheable: Puede invalidar caché
Respuestas comunes:
// Éxito - Sin contenido
HTTP/1.1 204 No Content
// Éxito - Con confirmación
HTTP/1.1 200 OK
{
"message": "Usuario eliminado",
"id": 123
}
// Recurso no encontrado (idempotente!)
HTTP/1.1 404 Not Found🎯 Métodos Adicionales
6. HEAD - Solo headers
Propósito: Igual que GET pero sin cuerpo
HEAD /api/users/123 HTTP/1.1
# Respuesta:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1234
Last-Modified: Mon, 15 Mar 2024 10:30:00 GMT
ETag: "abc123"
# Sin body!Usos comunes:
Verificar si recurso existe
Obtener metadata (tamaño, última modificación)
Validar caché
7. OPTIONS - Métodos disponibles
Propósito: Descubrir qué métodos soporta un recurso
OPTIONS /api/users HTTP/1.1
# Respuesta:
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS, HEAD
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Content-Length: 0Importante para CORS:
OPTIONS /api/users HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization8. CONNECT - Establecer túnel
Propósito: Establecer conexión a través de proxy
CONNECT api.ejemplo.com:443 HTTP/1.1
Host: api.ejemplo.com:443
# Usado para HTTPS a través de proxy9. TRACE - Depuración
Propósito: Eco para debugging (rara vez usado)
TRACE /api/test HTTP/1.1
Host: api.ejemplo.com
# El servidor devuelve la petición recibida📊 Tabla Comparativa de Métodos HTTP
| Método | Idempotente | Seguro | Cacheable | Body Request | Body Response |
|---|---|---|---|---|---|
| GET | ✅ Sí | ✅ Sí | ✅ Sí | ❌ No | ✅ Sí |
| POST | ❌ No | ❌ No | ❌ No* | ✅ Sí | ✅ Sí |
| PUT | ✅ Sí | ❌ No | ❌ No | ✅ Sí | ✅ Sí |
| PATCH | ❌ No* | ❌ No | ❌ No | ✅ Sí | ✅ Sí |
| DELETE | ✅ Sí | ❌ No | ❌ No | ❌ No | ⚠️ Opcional |
| HEAD | ✅ Sí | ✅ Sí | ✅ Sí | ❌ No | ❌ No |
| OPTIONS | ✅ Sí | ✅ Sí | ❌ No | ❌ No | ✅ Sí |
*Notas: POST puede cachearse con headers específicos. PATCH no es idempotente por naturaleza.
🔄 Flujos Completos por Método
Flujo GET Típico:
Cliente → GET /api/products/123
↓
Servidor → Busca producto 123
↓
→ 200 OK + JSON del producto
→ Headers: ETag, Last-Modified, Cache-ControlFlujo POST Típico:
Cliente → POST /api/orders
Content-Type: application/json
Body: {items: [...]}
↓
Servidor → Valida datos
→ Crea orden en DB
→ Genera ID único
↓
→ 201 Created
→ Location: /api/orders/456
→ Body: {id: 456, status: "pending"}Flujo DELETE Típico:
Cliente → DELETE /api/users/789
Authorization: Bearer token
↓
Servidor → Verifica autenticación
→ Busca usuario 789
→ Soft delete o hard delete
↓
→ 204 No Content
→ Invalida caché de /api/users/789🛡️ Consideraciones de Seguridad
GET vs POST para datos sensibles:
# ❌ MAL: Password en URL (visible en logs, historial)
GET /login?username=admin&password=secret
# ✅ BIEN: Password en body
POST /login
Content-Type: application/x-www-form-urlencoded
username=admin&password=secretIdempotencia y operaciones críticas:
# ❌ PELIGROSO: POST para transferencia bancaria
POST /api/transfer
{"amount": 1000, "to": "account456"}
# ✅ MEJOR: POST con idempotency key
POST /api/transfer
Idempotency-Key: tx-123-456-789
{"amount": 1000, "to": "account456"}📝 Buenas Prácticas RESTful
1. Usar métodos correctamente:
# ✅ CORRECTO
GET /api/users # Listar usuarios
POST /api/users # Crear usuario
GET /api/users/{id} # Ver usuario
PUT /api/users/{id} # Reemplazar usuario
PATCH /api/users/{id} # Actualizar parcial
DELETE /api/users/{id} # Eliminar usuario
# ❌ INCORRECTO
GET /api/users/create # Usar POST en su lugar
POST /api/users/123 # Usar PUT/PATCH
GET /api/users/delete/123 # Usar DELETE2. Semántica clara:
# ✅ Acciones como recursos
POST /api/users/{id}/activate # Mejor que PUT /api/users/{id}?action=activate
POST /api/orders/{id}/cancel # Mejor que DELETE /api/orders/{id}
# ✅ Recursos anidados
GET /api/users/{id}/orders # Órdenes del usuario
POST /api/users/{id}/orders # Crear orden para usuario3. Versionado:
# En URL
GET /api/v1/users
GET /api/v2/users
# En headers
GET /api/users
Accept: application/vnd.api.v2+json🔧 Ejemplos Prácticos con Código
Express.js:
// GET con query params
app.get('/api/products', (req, res) => {
const { category, page = 1, limit = 10 } = req.query;
// Lógica de búsqueda
res.json({ products: [...], page, total: 100 });
});
// POST con validación
app.post('/api/users', async (req, res) => {
const userData = req.body;
// Validar
if (!userData.email || !userData.password) {
return res.status(400).json({ error: 'Email y password requeridos' });
}
// Crear
const newUser = await User.create(userData);
// Responder
res.status(201)
.location(`/api/users/${newUser.id}`)
.json(newUser);
});
// PATCH parcial
app.patch('/api/users/:id', async (req, res) => {
const updates = req.body;
const user = await User.findById(req.params.id);
// Aplicar actualizaciones
Object.keys(updates).forEach(key => {
user[key] = updates[key];
});
await user.save();
res.json(user);
});Python Flask:
from flask import request, jsonify
@app.route('/api/books/<int:book_id>', methods=['GET', 'PUT', 'DELETE'])
def book_detail(book_id):
if request.method == 'GET':
book = Book.query.get_or_404(book_id)
return jsonify(book.to_dict())
elif request.method == 'PUT':
data = request.get_json()
book = Book.query.get_or_404(book_id)
# Actualizar todos los campos
book.title = data['title']
book.author = data['author']
book.save()
return jsonify(book.to_dict())
elif request.method == 'DELETE':
book = Book.query.get_or_404(book_id)
book.delete()
return '', 204 # No Content🚨 Errores Comunes
1. Usar GET para operaciones que modifican:
# ❌ NUNCA HAGAS ESTO
GET /api/delete-user?id=123
# ✅ En su lugar
DELETE /api/users/1232. POST para todo:
# ❌ API tipo RPC (anti-patrón REST)
POST /api
{
"method": "getUser",
"params": {"id": 123}
}
# ✅ API RESTful
GET /api/users/1233. No usar códigos HTTP correctos:
# ❌ Siempre 200, incluso para errores
HTTP/1.1 200 OK
{
"error": "Usuario no encontrado"
}
# ✅ Usar códigos apropiados
HTTP/1.1 404 Not Found
{
"error": "Usuario no encontrado"
}📚 Métodos HTTP/2 y HTTP/3
HTTP/2: Mismos métodos, pero multiplexados
# Múltiples peticiones en una conexión
Stream 1: GET /api/users
Stream 2: POST /api/orders
Stream 3: GET /api/products
# Todos en paralelo sobre TCPHTTP/3: Sobre QUIC (UDP)
# Conexiones más rápidas, menos latency
# Mismos métodos HTTP
# Recuperación mejorada de paquetes perdidos🎯 Resumen Final
| Método | Cuándo usarlo | Ejemplo real |
|---|---|---|
| GET | Leer datos | Listar productos, ver perfil |
| POST | Crear nuevo recurso | Crear usuario, enviar formulario |
| PUT | Reemplazar completamente | Actualizar configuración de usuario |
| PATCH | Actualizar parcialmente | Cambiar solo el email del usuario |
| DELETE | Eliminar recurso | Borrar cuenta, eliminar producto |
| HEAD | Verificar existencia | Check de salud API |
| OPTIONS | Descubrir capacidades | Preflight CORS |
Comentarios
Publicar un comentario