Lesson 1
Advanced RESTful Validation in Spring Boot with Kotlin
Introduction

Welcome to the course Advanced RESTful Techniques in Spring Boot. In your previous courses, you've covered Spring basics such as Inversion of Control (IoC), Dependency Injection (DI), and managing beans. You also learned how to create simple RESTful applications with CRUD endpoints. This course will take you a step further by exploring advanced topics like request body validation, error handling, pagination, and handling request and response headers. In this lesson, we'll focus on body validation.

Importance of Validation

Imagine you’re developing a check-in form for an airline application. The airline industry is highly regulated, and missing or incorrect information can lead to delays at the check-in counter. Therefore, users must provide their name, surname, age, and must confirm the accuracy of this information by selecting a checkbox.

Here's an example of a valid request body:

JSON
1{ 2 "firstName": "John", 3 "lastName": "Doe", 4 "age": 27, 5 "termsAndConditionsAccepted": true 6}

And here's an example of an invalid request body:

JSON
1{ 2 "firstName": "", // empty names are not allowed 3 "lastName": "Doe", 4 "age": 27, 5 "termsAndConditionsAccepted": false // falsy values are not allowed 6}
Methods of Validation

To ensure the integrity and accuracy of the data, various validation approaches can be employed:

  • Client-Side Validation: Here, the frontend application (e.g., built with React) checks the required fields before sending an HTTP request. This approach provides a more responsive user experience since errors are caught instantly. However, it is not foolproof, as users can still bypass it by making direct HTTP requests using tools such as CLI. Additionally, certain validation scenarios, such as verifying a coupon code against a database, cannot be handled solely on the client side.

  • Server-Side Validation: In this approach, the frontend sends the request regardless of the validation status, and the backend handles the validation logic. While this ensures a higher level of security and accuracy, it introduces a delay as users have to wait for the server response to see validation errors.

  • Combined Validation: This method uses both client-side and server-side validation, offering the best of both worlds. It provides immediate feedback to users and ensures the data’s integrity and security.

Enabling Validation Functionality

To add validation functionality to your ToDo List application, you’ll first need to include a specific dependency in your build.gradle.kts file. This dependency enables the use of validation annotations in your project:

Kotlin
1dependencies { 2 // Other dependencies... 3 4 implementation("org.springframework.boot:spring-boot-starter-validation") 5}

Adding this dependency ensures that Spring Boot can handle and support validation functionalities.

A Simple Data Class

Next, let's create a Kotlin data class that represents our data model. We can specify validation rules using annotations provided by the jakarta.validation.constraints package.

Kotlin
1package com.codesignal 2 3import jakarta.validation.constraints.NotBlank 4import jakarta.validation.constraints.Size 5 6data class TodoItem( 7 @field:NotBlank(message = "Title is mandatory") 8 @field:Size(min = 3, message = "Title must be at least 3 characters") 9 val title: String, 10 val completed: Boolean 11)

In this example, @field:NotBlank ensures that the title is not null and contains at least one non-whitespace character, while @field:Size(min = 3) ensures that the title is at least 3 characters long. By using these annotations, Spring Boot will automatically validate the fields based on the specified criteria.

Adding Validation to the Endpoint

To enable validation in your Spring Boot controller, you can use the @Valid annotation. This ensures that the incoming request body is validated according to the rules specified in the data class. Validation annotations are generally applied to HTTP methods that modify data, such as POST, PUT, and PATCH, since these methods typically involve submitting data that needs to be validated.

Kotlin
1package com.codesignal 2 3import org.springframework.web.bind.annotation.* 4import jakarta.validation.Valid 5 6@RestController 7class TodoController(private val todoRepository: TodoRepository) { 8 9 @PostMapping("/todo") 10 fun addTodo(@Valid @RequestBody todoItem: TodoItem): String { 11 // Assuming todoRepository is correctly set up with proper configuration 12 todoRepository.save(todoItem) 13 return "Todo added!" 14 } 15}

When the @Valid annotation is used, the validation process checks all the specified validation rules for the fields of the TodoItem class. If multiple fields are invalid, all errors are collected, and not just the first encountered error. This results in providing comprehensive feedback on all validation failures in a single response.

Useful Annotations

There are several other useful annotations provided by the jakarta.validation.constraints package. Here are a few:

  • @Min(value): Ensures that a numeric field is greater than or equal to the specified value.
  • @Max(value): Ensures that a numeric field is less than or equal to the specified value.
  • @Email: Validates that a string is a well-formed email address.
  • @Pattern(regexp): Validates that a string matches the specified regular expression.
  • @Future: Ensures that a date field is in the future.
  • @Past: Ensures that a date field is in the past.

These annotations provide a wide range of validation options to help you ensure data integrity.

Summary

In this lesson, you learned about the importance of data validation on both the frontend and backend, how to enable validation functionality in a Spring Boot application by adding necessary dependencies, defining validation rules using annotations in a Kotlin data class, and applying validation to an endpoint using the @Valid annotation. This sets the stage for practical exercises that will help you reinforce these concepts and prepare you for more advanced topics in upcoming lessons.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.