1. Introduction
In this quick tutorial, we’ll learn how to return HTTP 4XX errors in Spring applications.
2. Good HTTP Status Codes in Restful APIs
When designing a RESTful API, we must always design our APIs to return a meaningful HTTP response to the client so the outcome of the request is clear. For the happy path scenarios, the straightforward approach is to return the expected response. In this case, spring will set the header to HTTP 200 by default. However, when the request fails, we need to return an appropriate HTTP status code to the client. For example, when the client sends a request with invalid data, we should return an HTTP 4XX Request status code.
Spring provides several ways to return the appropriate response. Here, we’ll look at the ResponseEntity
class.
3. Bad Example of Handling HTTP Errors
Let’s consider a simple example where we have a controller method that returns the name of a student as a string:
@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?
}
Above, if we find the student, we return its name; otherwise, we need to handle the not-found scenario. For example, we might return an error string:
@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";
}
In this case, the controller method returns an HTTP 200 status code, which might break the client’s trust as the response is not what they expected. Instead, we should return an HTTP 404 Not Found status code.
4. Using ResponseEntity
To tackle this issue, we can use the ResponseEntity
class. By wrapping the return type of the controller method to ResponseEntity<?>
, we can set both the HTTP status code and the response body.
Now, we can’t return a string directly. Instead, we need to return an instance of 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();
}
Above, we use the ResponseEntity.ok()
method to return the student’s name if found. If the student is not found, we return an HTTP 404 Not Found status code using the ResponseEntity.notFound()
method.
Starting with Spring 4.1, the ResponseEntity
class provides several helper methods to create instances of ResponseEntity
with different HTTP status codes. This makes the code more readable and expressive.
For example, to return an HTTP 400 Bad Request status code, we can use the ResponseEntity.badRequest()
method or decide to build the response manually:
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
5. Benefits of Using ResponseEntity
Using the ResponseEntity<?>
as the return type for controller methods offers several advantages:
-Flexibility It allows for greater flexibility in defining the HTTP status code and response body. -Readability The code is more readable and expressive, especially when using the helper methods. -Consistency It encourages a consistent approach across your application for handling HTTP responses.
6. Conclusion
In this short article, we learned how to handle HTTP 4XX errors in a Spring application using the ResponseEntity
class. First, we explained the problem at hand. Then, we showed the importance of returning correct HTTP status codes in RESTful APIs. Finally, we demonstrated an example of using the ResponseEntity
class with its helper methods.