Express
Tutorial Express: Estados HTTP
Aprende a usar códigos de estado HTTP en Express para gestionar respuestas y errores en tus APIs REST de forma eficiente y profesional.
Aprende Express y certifícateCódigos de estado HTTP
Los códigos de estado HTTP son números de tres dígitos que el servidor web envía al cliente para indicar el resultado de una petición. Estos códigos forman parte fundamental del protocolo HTTP y permiten que tanto el navegador como las aplicaciones cliente comprendan qué ha ocurrido con su solicitud.
En Express, cada respuesta que enviamos incluye automáticamente un código de estado. Si no especificamos ninguno, Express asigna por defecto el código 200 (OK) para respuestas exitosas. Sin embargo, es una buena práctica establecer códigos de estado apropiados según el contexto de cada respuesta.
Categorías de códigos de estado
Los códigos de estado se organizan en cinco categorías principales, cada una identificada por el primer dígito:
- 1xx - Respuestas informativas: Indican que la petición se ha recibido y el proceso continúa
- 2xx - Respuestas exitosas: La petición se ha recibido, entendido y procesado correctamente
- 3xx - Redirecciones: Se necesita realizar alguna acción adicional para completar la petición
- 4xx - Errores del cliente: La petición contiene sintaxis incorrecta o no puede procesarse
- 5xx - Errores del servidor: El servidor falló al intentar procesar una petición válida
Códigos más utilizados en aplicaciones Express
En el desarrollo con Express, algunos códigos de estado aparecen con mayor frecuencia:
Códigos 2xx (Éxito):
app.get('/usuarios', (req, res) => {
const usuarios = obtenerUsuarios();
res.status(200).json(usuarios); // OK - Petición exitosa
});
app.post('/usuarios', (req, res) => {
const nuevoUsuario = crearUsuario(req.body);
res.status(201).json(nuevoUsuario); // Created - Recurso creado
});
app.delete('/usuarios/:id', (req, res) => {
eliminarUsuario(req.params.id);
res.status(204).send(); // No Content - Eliminación exitosa
});
Códigos 4xx (Errores del cliente):
app.get('/usuarios/:id', (req, res) => {
const usuario = buscarUsuario(req.params.id);
if (!usuario) {
return res.status(404).json({
error: 'Usuario no encontrado'
}); // Not Found
}
res.json(usuario);
});
app.post('/login', (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({
error: 'Email y contraseña son obligatorios'
}); // Bad Request
}
// Lógica de autenticación...
});
Códigos 5xx (Errores del servidor):
app.get('/datos', (req, res) => {
try {
const datos = procesarDatos();
res.json(datos);
} catch (error) {
console.error('Error procesando datos:', error);
res.status(500).json({
error: 'Error interno del servidor'
}); // Internal Server Error
}
});
Códigos específicos para APIs REST
Cuando desarrollamos APIs REST con Express, ciertos códigos de estado tienen significados específicos según la operación HTTP:
Para operaciones GET:
app.get('/productos/:id', (req, res) => {
const producto = buscarProducto(req.params.id);
if (!producto) {
return res.status(404).json({ error: 'Producto no encontrado' });
}
res.status(200).json(producto);
});
Para operaciones POST:
app.post('/productos', (req, res) => {
const { nombre, precio } = req.body;
if (!nombre || precio === undefined) {
return res.status(400).json({
error: 'Nombre y precio son obligatorios'
});
}
const nuevoProducto = crearProducto({ nombre, precio });
res.status(201).json(nuevoProducto);
});
Para operaciones PUT y PATCH:
app.put('/productos/:id', (req, res) => {
const producto = buscarProducto(req.params.id);
if (!producto) {
return res.status(404).json({ error: 'Producto no encontrado' });
}
const productoActualizado = actualizarProducto(req.params.id, req.body);
res.status(200).json(productoActualizado);
});
Códigos de redirección
Los códigos 3xx son especialmente útiles cuando necesitamos redirigir al cliente a otra ubicación:
app.get('/perfil', (req, res) => {
if (!req.session.usuario) {
return res.status(302).redirect('/login'); // Found - Redirección temporal
}
res.render('perfil');
});
app.get('/producto-antiguo/:id', (req, res) => {
// Redirección permanente a nueva URL
res.status(301).redirect(`/productos/${req.params.id}`);
});
Buenas prácticas con códigos de estado
Es importante ser consistente en el uso de códigos de estado a lo largo de toda la aplicación. Esto facilita tanto el desarrollo como el consumo de la API:
// Estructura consistente para errores
app.get('/api/usuarios/:id', (req, res) => {
try {
const usuario = buscarUsuario(req.params.id);
if (!usuario) {
return res.status(404).json({
success: false,
error: 'Usuario no encontrado',
code: 'USER_NOT_FOUND'
});
}
res.status(200).json({
success: true,
data: usuario
});
} catch (error) {
res.status(500).json({
success: false,
error: 'Error interno del servidor',
code: 'INTERNAL_ERROR'
});
}
});
La elección correcta del código de estado mejora significativamente la experiencia del desarrollador que consume nuestra API, ya que proporciona información clara sobre el resultado de cada operación sin necesidad de analizar el contenido de la respuesta.
Uso de res.status()
El método res.status() es la forma principal de establecer códigos de estado HTTP en Express. Este método pertenece al objeto de respuesta y nos permite definir explícitamente qué código queremos enviar al cliente antes de enviar la respuesta final.
La sintaxis básica de res.status() es sencilla: acepta un número entero que representa el código de estado HTTP y devuelve el objeto de respuesta, lo que permite encadenar otros métodos:
app.get('/ejemplo', (req, res) => {
res.status(200).json({ mensaje: 'Éxito' });
});
Encadenamiento de métodos
Una de las características más útiles de res.status() es que devuelve el objeto de respuesta, permitiendo el encadenamiento fluido con otros métodos de respuesta:
app.post('/usuarios', (req, res) => {
const nuevoUsuario = { id: 1, nombre: 'Juan' };
// Encadenamiento directo
res.status(201).json(nuevoUsuario);
});
app.delete('/usuarios/:id', (req, res) => {
// También funciona con send()
res.status(204).send();
});
app.get('/error', (req, res) => {
// Y con cualquier otro método de respuesta
res.status(500).render('error', { mensaje: 'Error interno' });
});
Establecimiento condicional del estado
El método res.status() es especialmente útil cuando necesitamos establecer diferentes códigos según las condiciones de nuestra lógica de negocio:
app.put('/productos/:id', (req, res) => {
const { id } = req.params;
const datosActualizacion = req.body;
const producto = buscarProducto(id);
if (!producto) {
return res.status(404).json({
error: 'Producto no encontrado'
});
}
if (!datosActualizacion.nombre) {
return res.status(400).json({
error: 'El nombre es obligatorio'
});
}
const productoActualizado = actualizarProducto(id, datosActualizacion);
res.status(200).json(productoActualizado);
});
Diferencia con statusCode
Express también proporciona la propiedad res.statusCode para establecer códigos de estado, pero res.status() es la forma recomendada por varias razones:
app.get('/comparacion', (req, res) => {
// Forma no recomendada
res.statusCode = 201;
res.json({ mensaje: 'Creado' });
// Forma recomendada
res.status(201).json({ mensaje: 'Creado' });
});
La ventaja principal de res.status() es que permite el encadenamiento y hace el código más legible y expresivo.
Validación automática
Express valida automáticamente que el código de estado proporcionado sea un número válido. Si pasamos un valor inválido, Express lanzará un error:
app.get('/invalido', (req, res) => {
try {
// Esto causará un error
res.status('invalid').json({ data: 'test' });
} catch (error) {
console.error('Error:', error.message);
res.status(500).json({ error: 'Error interno' });
}
});
Uso en funciones auxiliares
Una práctica común es crear funciones auxiliares que encapsulen el uso de res.status() para respuestas frecuentes:
// Funciones auxiliares para respuestas comunes
function enviarExito(res, data) {
return res.status(200).json({ success: true, data });
}
function enviarCreado(res, data) {
return res.status(201).json({ success: true, data });
}
function enviarError(res, codigo, mensaje) {
return res.status(codigo).json({ success: false, error: mensaje });
}
// Uso en las rutas
app.get('/usuarios/:id', (req, res) => {
const usuario = buscarUsuario(req.params.id);
if (!usuario) {
return enviarError(res, 404, 'Usuario no encontrado');
}
enviarExito(res, usuario);
});
app.post('/usuarios', (req, res) => {
const nuevoUsuario = crearUsuario(req.body);
enviarCreado(res, nuevoUsuario);
});
Establecimiento múltiple
Es importante recordar que res.status() debe llamarse antes de enviar la respuesta. Una vez que se ha enviado la respuesta con métodos como json(), send() o render(), no es posible modificar el código de estado:
app.get('/incorrecto', (req, res) => {
res.json({ mensaje: 'Datos enviados' });
// Esto no tendrá efecto y puede causar errores
// res.status(201); // ❌ Demasiado tarde
});
app.get('/correcto', (req, res) => {
// Primero establecemos el estado
res.status(201);
// Luego enviamos la respuesta
res.json({ mensaje: 'Datos enviados' });
});
Uso con async/await
Cuando trabajamos con operaciones asíncronas, res.status() se integra perfectamente con async/await:
app.post('/procesar', async (req, res) => {
try {
const resultado = await procesarDatosAsincrono(req.body);
if (!resultado) {
return res.status(422).json({
error: 'No se pudieron procesar los datos'
});
}
res.status(200).json(resultado);
} catch (error) {
console.error('Error en procesamiento:', error);
res.status(500).json({
error: 'Error interno del servidor'
});
}
});
El método res.status() es fundamental para crear APIs HTTP semánticamente correctas, ya que permite comunicar de forma precisa el resultado de cada operación al cliente que consume nuestra aplicación Express.
Otras lecciones de Express
Accede a todas las lecciones de Express y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Expressjs
Introducción Y Entorno
Instalación De Express
Introducción Y Entorno
Estados Http
Routing
Métodos Delete
Routing
Parámetros Y Query Strings
Routing
Métodos Get
Routing
Ejercicios de programación de Express
Evalúa tus conocimientos de esta lección Estados HTTP con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.