Express.js
Status codes y resultados de dominio
Explica cómo traducir resultados de aplicación a status HTTP, headers y errores públicos sin acoplar el dominio a Express ni exponer fallos internos.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
Express.js
Explica cómo traducir resultados de aplicación a status HTTP, headers y errores públicos sin acoplar el dominio a Express ni exponer fallos internos.
El status code clasifica el resultado HTTP; el body explica el caso concreto. Ambos deben derivarse del resultado real, no de excepciones genéricas.
Los códigos HTTP permiten que clientes, gateways y observabilidad distingan éxito, error del cliente, conflicto, indisponibilidad y fallo interno sin inspeccionar mensajes humanos.
resultado de aplicación
↓ mapeo HTTP
status + headers + body públicoEl dominio no debería importar Express ni devolver números HTTP. Puede expresar OrderNotFound, OrderConflict o InvalidCredentials; el boundary los traduce.
La operación fue aceptada o completada.
200 OK: éxito con representación.201 Created: recurso creado.202 Accepted: trabajo aceptado pero pendiente.204 No Content: éxito sin body.Redirección o uso de representación cacheada.
304 Not Modified: el cliente puede reutilizar su copia.La request no puede procesarse según el contrato o permisos actuales.
400: sintaxis o estructura inválida.401: falta autenticación válida.403: identidad conocida sin permiso.404: ruta o recurso no visible.405: método no permitido.409: conflicto con estado actual.412: precondición fallida.413: payload demasiado grande.415: media type no soportado.422: contenido válido a nivel sintáctico pero semánticamente inválido según el contrato.429: límite excedido.El servidor o una dependencia no pudo cumplir una request válida.
500: fallo inesperado.502: upstream devolvió una respuesta inválida.503: servicio temporalmente no disponible.504: timeout de gateway o upstream.Úsalo para lecturas y operaciones exitosas que devuelven representación.
Incluye Location cuando existe una URI del recurso creado.
No afirma que el trabajo terminó. Devuelve un identificador o URL para consultar estado.
{
"data": {
"jobId": "job_123",
"status": "queued"
}
}No lleva body. Es adecuado cuando la representación posterior no aporta valor.
No existe una única política universal. Una convención razonable:
La consistencia importa más que perseguir una frontera perfecta.
El cliente no presentó credenciales válidas. Puede incluir:
WWW-Authenticate: BearerLa identidad está autenticada, pero no tiene permiso.
Para reducir enumeración, algunos recursos no visibles se responden 404. Debe ser una política documentada.
Ambos comparten status, pero necesitan códigos internos distintos:
{ "code": "ROUTE_NOT_FOUND" }{ "code": "ORDER_NOT_FOUND" }409 Conflict sirve cuando el estado actual impide la operación:
Una constraint violation no debería convertirse automáticamente en 409 sin saber qué regla representa.
If-Match con ETag puede proteger updates:
PATCH /orders/123
If-Match: "version-7"Si la versión cambió, responde 412. Esto hace visible la concurrencia optimista en HTTP.
Un fallo de PostgreSQL no es siempre 500:
El status debe describir el impacto para el cliente, no copiar el nombre de la excepción técnica.
Un status no basta para decidir retry. Considera:
Retry-AfterUn 503 puede ser reintentable; un 409 normalmente requiere cambiar entrada o estado.
function mapError(error: unknown): HttpProblem {
if (error instanceof OrderNotFoundError) {
return { status: 404, code: 'ORDER_NOT_FOUND' };
}
if (error instanceof OrderConflictError) {
return { status: 409, code: 'ORDER_CONFLICT' };
}
if (error instanceof DependencyTimeoutError) {
return { status: 503, code: 'DEPENDENCY_UNAVAILABLE', retryable: true };
}
return { status: 500, code: 'INTERNAL_ERROR' };
}GET /orders normalmente responde 200 con [], no 404.
Puede devolver el mismo 201 o 200 con el recurso existente, según contrato.
Puede responder 204 ambas veces o 404 la segunda; ambas políticas pueden conservar idempotencia.
No reveles si el usuario existe mediante diferencias innecesarias en status o mensaje.
{ success: false }.Construye una matriz de resultados:
| Resultado | Status | Código |
| --- | ---: | --- |
| orden creada | 201 | — |
| input inválido | 422 | `VALIDATION_ERROR` |
| token ausente | 401 | `AUTHENTICATION_REQUIRED` |
| sin permiso | 403 | `FORBIDDEN` |
| orden no visible | 404 | `ORDER_NOT_FOUND` |
| estado incompatible | 409 | `ORDER_CONFLICT` |
| timeout externo | 503 | `DEPENDENCY_UNAVAILABLE` |
| bug inesperado | 500 | `INTERNAL_ERROR` |
Más granularidad ayuda a clientes, pero demasiados códigos poco comunes pueden volver inconsistente la API. Selecciona un vocabulario pequeño, correcto y documentado.
Headers y content negotiation desarrolla metadata que modifica autenticación, cache, representación y red.