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

http
GET /api/users/123 HTTP/1.1
Host: api.ejemplo.com
Accept: application/json

Caracterí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 - Éxito

  • 404 Not Found - Recurso no existe

  • 304 Not Modified - Usar caché

Ejemplos reales:

bash
# 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

http
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 exitosamente

  • 400 Bad Request - Datos inválidos

  • 409 Conflict - Recurso ya existe

Headers importantes:

text
Location: /api/users/456  # URL del nuevo recurso

Ejemplos reales:

bash
# 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

http
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:

bash
# 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

http
PATCH /api/users/123 HTTP/1.1
Content-Type: application/json

{
  "email": "nuevo.email@dominio.com"
}

Diferencia clave vs PUT:

javascript
// 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
// 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

http
DELETE /api/users/123 HTTP/1.1
Authorization: Bearer token123

Características:

  • Idempotente: Eliminar ya eliminado = mismo resultado

  • No seguro: Modifica el servidor

  • Sin Body: Generalmente sin cuerpo

  • Cacheable: Puede invalidar caché

Respuestas comunes:

http
// É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

http
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

http
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: 0

Importante para CORS:

http
OPTIONS /api/users HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

8. CONNECT - Establecer túnel

Propósito: Establecer conexión a través de proxy

http
CONNECT api.ejemplo.com:443 HTTP/1.1
Host: api.ejemplo.com:443

# Usado para HTTPS a través de proxy

9. TRACE - Depuración

Propósito: Eco para debugging (rara vez usado)

http
TRACE /api/test HTTP/1.1
Host: api.ejemplo.com

# El servidor devuelve la petición recibida

📊 Tabla Comparativa de Métodos HTTP

MétodoIdempotenteSeguroCacheableBody RequestBody 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:

text
Cliente → GET /api/products/123
         ↓
Servidor → Busca producto 123
         ↓
         → 200 OK + JSON del producto
         → Headers: ETag, Last-Modified, Cache-Control

Flujo POST Típico:

text
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:

text
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:

http
# ❌ 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=secret

Idempotencia y operaciones críticas:

http
# ❌ 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:

http
# ✅ 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 DELETE

2. Semántica clara:

http
# ✅ 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 usuario

3. Versionado:

http
# 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:

javascript
// 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:

python
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:

http
# ❌ NUNCA HAGAS ESTO
GET /api/delete-user?id=123

# ✅ En su lugar
DELETE /api/users/123

2. POST para todo:

http
# ❌ API tipo RPC (anti-patrón REST)
POST /api
{
  "method": "getUser",
  "params": {"id": 123}
}

# ✅ API RESTful
GET /api/users/123

3. No usar códigos HTTP correctos:

http
# ❌ 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

text
# 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 TCP

HTTP/3: Sobre QUIC (UDP)

text
# Conexiones más rápidas, menos latency
# Mismos métodos HTTP
# Recuperación mejorada de paquetes perdidos

🎯 Resumen Final

MétodoCuándo usarloEjemplo real
GETLeer datosListar productos, ver perfil
POSTCrear nuevo recursoCrear usuario, enviar formulario
PUTReemplazar completamenteActualizar configuración de usuario
PATCHActualizar parcialmenteCambiar solo el email del usuario
DELETEEliminar recursoBorrar cuenta, eliminar producto
HEADVerificar existenciaCheck de salud API
OPTIONSDescubrir capacidadesPreflight CORS

Comentarios

Entradas populares de este blog

¿Qué es el Modelo OSI?

bit -El codigo ASCII

38. Tema 1: Protocolos de comunicación.