1. Introducción
En este breve tutorial, aprenderemos cómo devolver errores HTTP 4XX en aplicaciones Spring.
2. Códigos de Estado HTTP Adecuados en APIs Restful
Al diseñar una API RESTful, siempre debemos diseñar nuestras APIs para que devuelvan una respuesta HTTP significativa al cliente, de modo que el resultado de la solicitud sea claro. Para los escenarios de camino feliz, el enfoque más sencillo es devolver la respuesta esperada. En este caso, spring establecerá el encabezado en HTTP 200 por defecto. Sin embargo, cuando la solicitud falla, necesitamos devolver un código de estado HTTP apropiado al cliente. Por ejemplo, cuando el cliente envía una solicitud con datos inválidos, deberíamos devolver un código de estado HTTP 4XX Request.
Spring proporciona varias formas de devolver la respuesta adecuada. Aquí, analizaremos la clase ResponseEntity
.
3. Mal Ejemplo de Manejo de Errores HTTP
Consideremos un ejemplo simple donde tenemos un método de controlador que devuelve el nombre de un estudiante como una cadena:
@GetMapping(value = "/student/{id}/name")
@ResponseBody
public String getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return student.get().getName();
}
// --- What to do here?
}
Arriba, si encontramos al estudiante, devolvemos su nombre; de lo contrario, necesitamos manejar el escenario de no encontrado. Por ejemplo, podemos devolver una cadena de error:
@GetMapping(value = "/student/{id}/name")
@ResponseBody
public String getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return student.get().getName();
}
return "Student not found";
}
En este caso, el método del controlador devuelve un código de estado HTTP 200, lo que podría romper la confianza del cliente ya que la respuesta no es lo que esperaban. En su lugar, deberíamos devolver un código de estado HTTP 404 Not Found.
4. Usando ResponseEntity
Para abordar este problema, podemos utilizar la clase ResponseEntity
. Al envolver el tipo de retorno del método del controlador con ResponseEntity<?>
, podemos establecer tanto el código de estado HTTP como el cuerpo de la respuesta.
Ahora, no podemos devolver una cadena directamente. En su lugar, necesitamos devolver una instancia de ResponseEntity
:
@GetMapping(value = "/student/{id}/name")
public ResponseEntity<?> getStudentNameById(@PathVariable String id) {
Optional<Student> student = studentService.findById(matchId);
if(student.isPresent()){
return ResponseEntity.ok(student.get().getName());
}
return ResponseEntity.notFound().build();
}
Arriba, utilizamos el método ResponseEntity.ok()
para devolver el nombre del estudiante si se encuentra. Si no se encuentra al estudiante, devolvemos un código de estado HTTP 404 Not Found utilizando el método ResponseEntity.notFound()
.
A partir de Spring 4.1, la clase ResponseEntity
proporciona varios métodos auxiliares para crear instancias de ResponseEntity
con diferentes códigos de estado HTTP. Esto hace que el código sea más legible y expresivo.
Por ejemplo, para devolver un código de estado HTTP 400 Bad Request, podemos utilizar el método ResponseEntity.badRequest()
o decidir construir la respuesta manualmente:
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
5. Beneficios de usar ResponseEntity
Utilizar ResponseEntity<?>
como tipo de retorno para los métodos del controlador ofrece varias ventajas:
-Flexibilidad Permite una mayor flexibilidad en la definición del código de estado HTTP y del cuerpo de la respuesta.
-Legibilidad El código es más legible y expresivo, especialmente al utilizar los métodos auxiliares.
-Consistencia Fomenta un enfoque consistente en toda la aplicación para manejar las respuestas HTTP.
6. Conclusión
En este breve artículo, aprendimos a manejar los errores HTTP 4XX en una aplicación Spring utilizando la clase ResponseEntity
. Primero, explicamos el problema en cuestión. Luego, mostramos la importancia de devolver códigos de estado HTTP correctos en las APIs RESTful. Finalmente, demostramos un ejemplo de uso de la clase ResponseEntity
con sus métodos auxiliares.