50% OFF Plus
--:--:--
¡Obtener!

Estados HTTP

Intermedio
Express
Express
Actualizado: 20/06/2025

¡Desbloquea el curso de Express completo!

IA
Ejercicios
Certificado
Entrar

Mira la lección en vídeo

Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.

Desbloquear Plan Plus

Có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()

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

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.

Aprendizajes de esta lección de Express

  • Comprender la función y categorías de los códigos de estado HTTP.
  • Aprender a utilizar res.status() para establecer códigos de estado en Express.
  • Identificar los códigos de estado más comunes en APIs REST y su significado.
  • Aplicar buenas prácticas en el manejo de códigos de estado para mejorar la comunicación con el cliente.
  • Integrar res.status() con operaciones asíncronas y funciones auxiliares para respuestas consistentes.

Completa este curso de Express y certifícate

Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración