For the best experience, try the new Microsoft Edge browser recommended by Microsoft (version 87 or above) or switch to another browser Ė Google Chrome / Firefox / Safari
OK

How Software Teams Must Centralize Exception Rest API in Spring Boot

Karthik Pillai, Senior Content Writer
Centralized-Exception-Handling-Xoriant

Unexpected situations may arise in any software application or system when the program goes south. At this crucial juncture, exception handling comes into play. 
Exception handling is a very crucial part of the application, it takes care of defining the steps to be taken in case of any unforeseen circumstances at the time of execution. While working on API development, we need to clearly define what a client or a caller does if the API does not respond as expected. The API response, in this case, should be meaningful enough so that the client can take corrective action.

In this article, we are going to look at how this is done for REST APIs in Spring Boot with the help of ControllerAdvice and ExceptionHandler annotations. These annotations help us define a global component that acts as an interceptor to intercept all the exceptions across all the handlers in the application and handle them at one central place, separating it from the rest of the application logic and avoiding duplication of exception handling code.

Demo Application

Let us consider a simple employee management application with two REST APIs exposed. 

  • GET request: To fetch an employee by id from DB
  • POST request: Save the employee data to DB

Controller Class

A controller class processes incoming REST API requests, prepares a model and returns the view as a response.

Controller Class - Xoriant Blog

Service Class

Service class ensures class files are used to write business logic in a different layer and are separated from RestController class file.

Service Class - Xoriant Blog
 

Repository Class

Repository Class indicates the class providing mechanism for storage, retrieval, search, update and delete operation on objects. 

Repository Class - Xoriant Blog
 

Entity Class

Entity class defines that the class is an entity and is appropriately mapped to the database table.

Entity Class - Xoriant Blog
 

Sample Requests

When we send the requests to these two APIs with valid data, output looks like below:

[POST] Create Employee 

Sample Requests - Xoriant Blog
 

[GET] Fetch Employee 

Fetch Employee - Xoriant Blog

Let us now invoke these APIs with invalid data.

[POST] Save Employee with Null ID

Save Employee - Xoriant Blog

[GET] Fetch Employee with Invalid ID

Fetch Employee Invalid - Xoriant Blog

Both responses, in case of invalid request data, look cryptic and not something we may want to send to the user.

Spring Boot provides us a way where we can handle these kinds of exception scenarios, by intercepting the exception before they are sent to the user and stub meaningful response and send relevant details to the user.

Let us look at two Spring Boot annotations that would help us do this: 

 

  • @ControllerAdvice:¬†This annotation was introduced in Spring 3.2 version and is used to handle the exceptions globally, we will create a class annotated with this, with handler methods handling each type of exception.
     
  • @ExceptionHandler: In the class annotated with @ControllerAdvice, we will have handler methods for each type of exception that may occur in an application. These methods would construct the user-friendly response and send it back to the user.

Demo Application Modifications to Handle Invalid GET Request

Custom Exception Class

We have created a custom exception class as below to represent an exception thrown when the employee, we are trying to retrieve, is not found in the DB.

Custom Exception Class - Xoriant Blog

Updated Service Class 

We will modify service implementation to get to throw this exception when there is no data found.

Updated Service Class - Xoriant Blog

This exception would be caught by a method annotated with the handler method in the global API exception handler and the custom response would be sent back.

Global Exception Handler Class
We will create a new class and it will be annotated with @ControllerAdvice to intercept the exceptions and handle them centrally in one place.

This class would have handler methods for all the exceptions we want to catch in the handler code and would create a custom response stubbing the details relevant to the user and send it back. In this case, we will send the exception message, next steps to take, and timestamp when it occurred.

Global Exceptional Class Handler - Xoriant Blog

Custom Response Class

Custom response would look like below, we can enhance this as needed to send the response fields we want.

Custom Response Class - Xoriant Blog

After the above changes, when we hit the same request with invalid data, the response looks much simpler and something which can help a user understand what has gone wrong in the API call.

[GET] Fetch Employee with Invalid ID

Fetch Employee Invalid - Xoriant Blog

Changes to Demo Application to Handle REST API Validations

We can also use Global API Exception Handler to customize the response sent as part of inbuilt Rest API constraint validations when any of the validation fails.  For e.g., will add @NotNull validation on the id field as below.

DTO Class with Constraint Validation Added

DTO Class Constraint Validation - Xoriant Blog

If we do not catch this in the global API handler, the default response looks like below when the validation fails, which is not very helpful to the user.

[POST] Save Employee with Null ID

Save Employee Null - Xoriant Blog

Global API Exception Handler Changes for Constraint Validation Failure

We will add a custom API handler method for the ‚ÄúMethodArgumentNotValidException‚ÄĚ exception which is thrown when any of the constraint validation fails.

Global API Exception Handler Constraint Validation - Xoriant Blog

After this is added, when we hit the save API with invalid data the response looks below which sends the custom response we stubbed in the handler.

[POST] Save Employee with Null ID

Save Employee Null ID - Xoriant Blog

Best Practices of Exception Handling in Spring Boot

  • Create custom exceptions for specific cases with dedicated handlers in the Global API Exception Handler.
  • Even if we are catching the exception in the handler, we should make sure that the exception stack trace is logged in server logs with proper severity to make debugging easier.
  • Refrain from sending the stack trace of the exception to the user.
  • If there is a need to use custom application error codes, choose a range that does not collide with existing HTTP error codes.

Way Forward

Software engineering teams can use Global API Exception Handler to globally handle exceptions for REST APIs. In addition, we can add custom application-specific error codes and stub in custom response and send back. Handling exceptions globally makes it easy to decouple the exception handling logic at one place keeping it separate from the rest of the application code.

Looking to make your engineering teams’ delivery excellent and effective?

We're Here to Help!

Leave a reply

Your email address will not be published. Required fields are marked*

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <p> <span> <div> <h1> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id> <hr> <br> <br /> <ul type> <ol start type> <li> <dl> <dt> <dd> <em> <b> <u> <i> <strong> <del> <ins> <sub> <sup> <quote> <blockquote cite> <pre> <address> <code> <strike> <caption>
  • Lines and paragraphs break automatically.