In this tutorial, you will learn to implement an REST API Validation + Error Handling Example in Spring Boot

REST API validation can be implemented by using Java Bean Validation API, Hibernate Validator and Unified Expression Language. Check this tutorial if you're new to Java Bean Validation API

Error Handling for REST in Spring can be implemented by extending ResponseEntityExceptionHandler and using @ControllerAdvice class annotation to apply globally to all controllers

What you'll need

  • JDK 8+ or OpenJDK 8+
  • Maven 3+

Stack

  • Java Bean Validation API, Hibernate Validator and Unified Expression Language
  • Spring Boot with @RestController, @RequestMapping, @Validated, ResponseEntityExceptionHandler, @ControllerAdvice and @ExceptionHandler
  • JPA, Hibernate and HSQL
  • Lombok with @Builder

Project structure

├── src
│   └── main
│       ├── java
│       │   └── com
│       │       └── hellokoding
│       │           └── springboot
│       │               └── restful
│       │                   ├── product
│       │                   │   ├── Product.java
│       │                   │   ├── ProductAPI.java
│       │                   │   ├── ProductIDExisting.java
│       │                   │   ├── ProductIDExistingValidator.java
│       │                   │   ├── ProductRepository.java
│       │                   │   └── ProductService.java
│       │                   ├── Application.java
│       │                   ├── ExceptionHandler.java
│       │                   └── ResponseDTO.java
│       └── resources
│           └── ValidationMessages.properties
└── pom.xml

Dependencies

Include spring-boot-starter-validation into your pom.xml

<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>  

spring-boot-starter-validation contains

  • hibernate-validator: an implementation of Java Bean Validation API

  • tomcat-embed-el: an implementation of Java Unified Expression Language (EL)

Full content of pom.xml as below


Define data model and validation constraints

Define data model


@NotNull, @Size and @Min are built-in constraints

@ProductIDExisting is a custom constraint defined as below

{NotNull} is message templates, its value will be replaced at run time by the below ValidationMessages.properties

Define custom constraint


{ProductIDExisting} is a message template. Its value will be replaced at run time by the below ValidationMessages.properties

Define custom constraint validator


Custom the validation messages


Define ResponseDTO, REST API and API Exception Handler


ResponseDTO is defined to unify REST API response data format to client


REST APIs are defined with @RestController, @RequestMapping, @GetMapping, @PostMapping, @@PutMapping and @DeleteMapping

@Valid indicates validation cascading: constraints defined on the object and its properties are be validated when the property, method parameter or method return type is validated

@Validated is a variant of @Valid indicating that a specific class is supposed to be validated at the method level. In this example, it is using to trigger validation for @ProductIDExisting method parameters


ResponseEntityExceptionHandler provides centralized exception handling across all @RequestMapping methods through @ExceptionHandler methods which return ResponseEntity

@ControllerAdvice is a specialization for classes that declare @ExceptionHandler, @InitBinder, or @ModelAttribute methods to be shared across multiple @Controller classes

Run and Test

Run with Maven

Type command mvn clean spring-boot:run at your project root directory to run the application

Test with cURL

curl -i -X PUT -H "Content-Type:application/json" -d "{\"id\": 1, \"name\" : \"Hello Koding\", \"description\": \"Practical Coding Courses, Tutorials and Examples\", \"price\":1}" http://localhost:8080/api/v1/products/1

Expected output

{"status":"400 BAD_REQUEST","message":"Product ID 1 is not existing","body": null}

Source code

https://github.com/hellokoding/hellokoding-courses/tree/master/springboot-examples/springboot-restapi-validation