Definición
DELETE es un método HTTP que elimina un recurso del servidor. Cuando un cliente envía una petición DELETE a una URI de recurso, el servidor debe eliminar ese recurso o marcarlo como eliminado. DELETE es idempotente: si eliminas un recurso que ya está eliminado, el resultado es el mismo: el recurso no existe.
La característica clave de DELETE es la irreversibilidad: una vez ejecutado exitosamente, las peticiones GET subsiguientes a la misma URI deberían devolver 404 Not Found (o 410 Gone si quieres indicar que el recurso existió previamente). Sin embargo, muchos sistemas en producción implementan “eliminaciones lógicas” donde los recursos se marcan como eliminados en lugar de eliminarse físicamente.
DELETE es fundamental para las operaciones CRUD RESTful, representando la “D” (Delete/Destroy). A diferencia de métodos inseguros como POST, DELETE debe implementarse cuidadosamente con verificaciones de autorización apropiadas para prevenir pérdida de datos accidental o maliciosa.
Ejemplo
Cuenta de Usuario - Eliminación Física:
DELETE /api/users/123 HTTP/1.1
// Respuesta: 204 No Content (eliminado exitosamente)
Publicación de Blog - Eliminar Contenido:
DELETE /api/posts/456 HTTP/1.1
// Respuesta: 200 OK con confirmación de eliminación
{
"message": "Post deleted successfully",
"deletedAt": "2026-01-09T12:00:00Z"
}
Carrito de Compras - Limpiar Todos los Artículos:
DELETE /api/cart HTTP/1.1
// Respuesta: 204 No Content
Almacenamiento de Archivos - Eliminar Documento:
DELETE /api/files/report-2024.pdf HTTP/1.1
Authorization: Bearer token...
// Respuesta: 200 OK
{
"deleted": true,
"filename": "report-2024.pdf",
"size": 2048576
}
Colección - Eliminar Artículo Específico:
DELETE /api/playlists/789/songs/101 HTTP/1.1
// Respuesta: 204 No Content
Analogía
Borrar una Pizarra: DELETE es como borrar algo de una pizarra. Una vez que lo limpias, se ha ido. Si intentas borrar el mismo lugar otra vez, no pasa nada: ya está vacío. La acción es idempotente.
Cancelar una Reserva: Cuando haces DELETE de una reserva de hotel, se elimina del sistema. Si intentas cancelar la misma reserva otra vez, el sistema te dice que ya no existe, pero el resultado final es el mismo: no hay reserva.
Eliminar Libros de Biblioteca: Piensa en retirar un libro permanentemente (eliminarlo de circulación). Ya sea que lo elimines una vez o intentes eliminarlo diez veces, el resultado es idéntico: el libro ya no está disponible.
Ejemplo de Código
// DELETE - Eliminar recurso de usuario
DELETE /api/users/789 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// Respuesta - 204 No Content (respuesta estándar)
HTTP/1.1 204 No Content
Date: Thu, 09 Jan 2026 12:00:00 GMT
// DELETE - Con cuerpo de confirmación (menos común)
DELETE /api/posts/456 HTTP/1.1
Authorization: Bearer token...
// Respuesta - 200 OK con cuerpo
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "deleted",
"id": 456,
"title": "My Blog Post",
"deletedAt": "2026-01-09T12:00:00Z"
}
// DELETE - Comportamiento idempotente (ya eliminado)
DELETE /api/users/789 HTTP/1.1
// Respuesta - 404 Not Found (ya eliminado)
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": "not_found",
"message": "User not found"
}
// Alternativa - 410 Gone (indica que existió antes)
HTTP/1.1 410 Gone
Content-Type: application/json
{
"error": "resource_deleted",
"message": "User was deleted",
"deletedAt": "2026-01-09T12:00:00Z"
}
// DELETE - Eliminación condicional con ETag
DELETE /api/documents/123 HTTP/1.1
If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
// Respuesta - 204 No Content (coincide, eliminado)
HTTP/1.1 204 No Content
// DELETE - Precondición fallida
DELETE /api/documents/123 HTTP/1.1
If-Match: "wrong-etag"
// Respuesta - 412 Precondition Failed
HTTP/1.1 412 Precondition Failed
Content-Type: application/json
{
"error": "precondition_failed",
"message": "Resource has been modified since last fetch"
}
// DELETE - Error de autorización
DELETE /api/users/999 HTTP/1.1
Authorization: Bearer invalid-token
// Respuesta - 403 Forbidden
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"error": "forbidden",
"message": "You don't have permission to delete this resource"
}
// DELETE - Eliminación lógica (recurso marcado como inactivo)
DELETE /api/accounts/555 HTTP/1.1
// Respuesta - 200 OK
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 555,
"status": "deleted",
"deletedAt": "2026-01-09T12:00:00Z",
"restorable": true,
"restoreUntil": "2026-02-09T12:00:00Z"
}
Diagrama
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: DELETE /api/users/123
Note over Client,Server: Cabecera de autorización
Server->>Server: Verificar autorización
Note over Server: Comprobar permisos
Server->>Database: Verificar si el recurso existe
Database-->>Server: Recurso encontrado
Server->>Database: DELETE from users WHERE id=123
Database-->>Server: Eliminado exitosamente
Server-->>Client: 204 No Content
Note over Server,Client: Recurso eliminado
Client->>Server: DELETE /api/users/123 (otra vez)
Note over Client,Server: Idempotente - misma petición
Server->>Database: Verificar si el recurso existe
Database-->>Server: No encontrado
Server-->>Client: 404 Not Found
Note over Server,Client: Ya eliminado (idempotente)
Notas de Seguridad
CRÍTICO - …
Configuración y Validación:
- Implementar verificaciones de autorización estrictas antes de eliminar recursos.
- Los usuarios solo deben eliminar recursos que poseen o para los que tienen permisos explícitos.
- Usar tokens de autenticación para verificar identidad.
- Nunca permitir peticiones DELETE anónimas para datos sensibles.
- Considerar implementar eliminaciones lógicas para datos críticos para permitir recuperación.
- Registrar todas las operaciones DELETE con identidad de usuario, marca de tiempo y detalles del recurso para pistas de auditoría.
Monitoreo y Protección:
- Implementar limitación de tasa para prevenir ataques de eliminación.
- Usar ETags o verificaciones de versión (cabecera If-Match) para prevenir eliminaciones accidentales de recursos modificados.
- Considerar requerir confirmación adicional para eliminaciones irreversibles.
- Implementar CORS apropiadamente: las peticiones DELETE disparan verificaciones de preflight OPTIONS.
- Ser cauteloso con eliminaciones en cascada: asegurar que los usuarios entiendan qué se eliminará.
- Considerar implementar patrones de papelera/reciclaje para recursos importantes.
Mejores Prácticas
- Devolver 204 No Content: Respuesta exitosa estándar (no se necesita cuerpo)
- Usar 200 OK si se devuelven datos: Incluir detalles de eliminación en el cuerpo de respuesta
- Implementar autorización: Verificar que el usuario tiene permiso para eliminar
- Hacerlo idempotente: Eliminar un recurso ya eliminado debe tener éxito
- Devolver 404 Not Found: Después de una eliminación exitosa, GET debe devolver 404
- Considerar eliminaciones lógicas: Marcar como eliminado en lugar de eliminación física
- Soportar ETags: Usar If-Match para eliminaciones condicionales
- Registrar eliminaciones: Pista de auditoría para cumplimiento y recuperación
- Manejar cascadas cuidadosamente: Documentar qué más se elimina
- Proporcionar deshacer/restaurar: Para recursos críticos, permitir período de recuperación
Errores Comunes
Devolver 200 OK con cuerpo vacío en lugar de 204 No Content. No implementar autorización apropiada, permitiendo a usuarios eliminar recursos de otros. Hacer DELETE no idempotente: devolver error 500 cuando el recurso ya está eliminado en lugar de 404/410. Incluir cuerpo de petición en DELETE (algunos servidores lo ignoran). No registrar eventos de eliminación para propósitos de auditoría. Implementar eliminaciones físicas para datos críticos sin mecanismo de respaldo/restauración. Olvidar implicaciones de eliminación en cascada: eliminar padre sin manejar hijos huérfanos. No soportar eliminaciones condicionales con ETags, arriesgando eliminación de recursos modificados. Permitir DELETE sin autenticación para recursos sensibles. Devolver 204 pero no eliminar realmente el recurso (eliminación lógica sin documentación).