Definición
Una respuesta HTTP es un mensaje enviado desde un servidor de vuelta a un cliente después de procesar una petición HTTP. La respuesta indica si la petición tuvo éxito o falló, y opcionalmente incluye los datos solicitados o detalles del error.
La respuesta consiste en tres partes principales:
- Línea de Estado - Versión HTTP, código de estado y frase de razón
- Cabeceras - Metadatos sobre la respuesta (tipo de contenido, cacheo, autenticación)
- Cuerpo (opcional) - Los datos reales (HTML, JSON, XML, archivos, etc.)
Las respuestas HTTP siguen el formato definido en RFC 7231 y son esenciales para la comunicación cliente-servidor en APIs REST y aplicaciones web.
Ejemplo
Una respuesta HTTP 200 OK típica con datos JSON:
HTTP/1.1 200 OK
Date: Thu, 09 Jan 2026 10:30:00 GMT
Content-Type: application/json
Content-Length: 142
Cache-Control: max-age=3600
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
{
"id": 123,
"name": "Alice Smith",
"email": "[email protected]",
"role": "developer",
"createdAt": "2026-01-05T14:22:00Z"
}
Una respuesta 404 Not Found:
HTTP/1.1 404 Not Found
Date: Thu, 09 Jan 2026 10:30:00 GMT
Content-Type: application/json
Content-Length: 58
{
"error": "User not found",
"userId": 999
}
Ejemplo de Código
JavaScript (Fetch API):
const fetchUser = async (userId) => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`, {
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
}
});
// Propiedades del objeto Response
console.log('Status:', response.status); // 200
console.log('Status Text:', response.statusText); // "OK"
console.log('Headers:', response.headers);
// Verificar si la respuesta es OK (estado 200-299)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Parsear cuerpo JSON
const data = await response.json();
// Acceder a cabeceras de respuesta
const contentType = response.headers.get('Content-Type');
const etag = response.headers.get('ETag');
console.log('Content-Type:', contentType);
console.log('ETag:', etag);
console.log('User Data:', data);
return data;
} catch (error) {
if (error.name === 'AbortError') {
console.error('Request timeout');
} else {
console.error('Error:', error.message);
}
throw error;
}
};
// Uso
fetchUser(123)
.then(user => console.log('User:', user))
.catch(error => console.error('Failed:', error));
Python (librería requests):
import requests
def fetch_user(user_id):
try:
response = requests.get(
f'https://api.example.com/users/{user_id}',
headers={
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
},
timeout=10
)
# Propiedades del objeto Response
print(f'Status Code: {response.status_code}') # 200
print(f'Reason: {response.reason}') # "OK"
print(f'Headers: {response.headers}')
# Verificar si la respuesta es exitosa (2xx)
response.raise_for_status()
# Parsear cuerpo JSON
data = response.json()
# Acceder a cabeceras de respuesta
content_type = response.headers.get('Content-Type')
etag = response.headers.get('ETag')
print(f'Content-Type: {content_type}')
print(f'ETag: {etag}')
print(f'User Data: {data}')
return data
except requests.exceptions.HTTPError as e:
print(f'HTTP Error: {e}')
raise
except requests.exceptions.Timeout:
print('Request timeout')
raise
except requests.exceptions.RequestException as e:
print(f'Request failed: {e}')
raise
# Uso
try:
user = fetch_user(123)
print(f'User: {user}')
except Exception as e:
print(f'Failed: {e}')
Diagrama
sequenceDiagram
participant Client
participant Server
Note over Client,Server: Fase de Petición
Client->>Server: Petición HTTP
Note right of Server: GET /api/users/123
Note over Server: Procesamiento
Server->>Server: Autenticar
Server->>Server: Autorizar
Server->>Server: Obtener Datos
Server->>Server: Formatear Respuesta
Note over Server: Construir Respuesta
Server->>Server: Establecer Código de Estado
Server->>Server: Añadir Cabeceras
Server->>Server: Serializar Cuerpo
Note over Client,Server: Fase de Respuesta
Server->>Client: Respuesta HTTP
Note left of Client: Estado: 200 OK
Cabeceras: Content-Type, ETag
Cuerpo: datos JSON
Note over Client: Manejar Respuesta
Client->>Client: Verificar Código de Estado
Client->>Client: Parsear Cabeceras
Client->>Client: Deserializar Cuerpo
Client->>Client: Actualizar UI/Estado
Analogía
Piensa en una respuesta HTTP como recibir tu pedido en un restaurante:
- Línea de Estado → “Aquí está tu pedido” (éxito) o “Lo siento, no tenemos” (fallo)
- Cabeceras → Información nutricional, temperatura, advertencias de alérgenos (metadatos)
- Cuerpo → La comida real (datos que solicitaste)
El camarero (servidor) trae tu comida (respuesta) con todos los detalles sobre lo que pediste.
Mejores Prácticas
- Usar Códigos de Estado Apropiados - 2xx para éxito, 4xx para errores de cliente, 5xx para errores de servidor
- Incluir Cabeceras Descriptivas -
Content-Type,Cache-Control,ETagpara cacheo - Proporcionar Detalles de Error - Incluir mensajes de error útiles en el cuerpo de respuesta
- Establecer Content-Type Correcto - Coincidir con el formato del cuerpo (application/json, text/html, etc.)
- Habilitar Compresión - Usar
Content-Encoding: gzippara respuestas grandes - Incluir Cabeceras CORS - Establecer
Access-Control-Allow-Originpara peticiones cross-origin - Usar HTTP/2 - Habilitar multiplexación y compresión de cabeceras para mejor rendimiento
Errores Comunes
- Código de Estado Incorrecto - Devolver 200 OK para errores, o 404 cuando 401/403 es apropiado
- Content-Type Faltante - No especificar el formato del cuerpo de respuesta
- Sin Detalles de Error - Devolver errores genéricos sin mensajes útiles
- Enviar Datos Sensibles - Incluir contraseñas, IDs internos o trazas de stack
- Sin Cabeceras de Cacheo - No establecer
Cache-ControloETagpara recursos cacheables - Formato Inconsistente - Cambiar estructura de respuesta entre endpoints
- Sin Información de Rate Limit - No incluir cabeceras
X-RateLimit-*