Spring boot API architecture (part 1) — request/bean validation and JPA buddy tips

Mayank Yaduvanshi
3 min readJun 29, 2023

This is a simple demonstration of one way of handling and validating the api requests (Bean validation) on controller in Spring boot.

Start by adding the required maven dependencies

<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>

<!--validation-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>

<!--JPA-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

JPA Buddy — IntelliJ IDEs Plugin | Marketplace (jetbrains.com)

Controller

Create an controller to handler the CRUD requests related to a user.

UserController.java — phase 1

@RestController
@RequestMapping(value = "users")
public class UserController {

// todo: add user related apis
}

Now let’s create an simple user class (JPA entity)

// User.java

@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Table(name = "users")
@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private UUID id;

@Column(name = "email")
private String email;

@Column(name = "email")
private String phone;

@Column(name = "email")
private String name;

}

[JPA buddy] If you connected your database to Intellij IDEA, and installed JPA buddy plugin then you can easily create an entity class with the help of plugin without writing a single line of code.

(Database tools and SQL | IntelliJ IDEA Documentation (jetbrains.com))

(1) How to create JPA Entities in IntelliJ IDEA | JPA Buddy — YouTube

DTO

Because it is not a good practice to return the entity class itself in response, we ofter create an replica of it called DTO (data transfer object).

create a DTO for user entity

// UserDto.java

@Data
public class UserDto {
UUID id;
String email;
String phone;
String name;
}

Generally UserDto is enough to control the data being transferred between layers, but an extra class\’es can be added to handle api requests that tries to modify the user (data in table). We can name these classes with prefix of action that they are tend to do like -

CreateUserRequest — DTO class to handle POST requests (or create) for user

UpdateUserRequest — DTO class to handle PUT requests (or update) for user

A request class generally contains the minimal information required to do the action, whereas DTO can contain all the information about an entity and its relations.

Creating requests with validations

// Create user 
// only email, phone and name is enough to create user

@Data
public class CreateUserRequest {

@NotBlank
@Email
String email;

@NotBlank
String phone;

@NotBlank
String name;
}

// Update user
// only name of the user can be updated (not email and phone)

@Data
public class UpdateUserRequest {

@NotBlank
String name;
}

Take a close look at the above classes, you will see some annotations applied to the fields for validations. Let’s understand their meanings

@NotBlank — validates that field value should not be null or empty

@Email — validates that field value should be an email

Their are many other validations annotations are also available — Validation with Spring Boot — the Complete Guide (reflectoring.io)

Validating request body

user controller — phase 2

@PostMapping
public ResponseEntity<UserDto> createUser(
@RequestBody @Valid CreateUserRequest requestBody
) {
// todo: implement
}

@PutMapping
public ResponseEntity<UserDto> updateUser(
@RequestBody @Valid UpdateUserRequest requestBody
) {
// todo: implement
}

Notice that we have put @Valid annotation before parameter requestBody, this will perform all the validations applied on class at runtime. If any invalid values are found then spring boot throws Bad request error itself with error messages like which field has what invalidations.

This is all for this part, in the next part will see how to convert entity to DTO and vice-versa efficiently, handling requests and errors.

--

--

Mayank Yaduvanshi
Mayank Yaduvanshi

Written by Mayank Yaduvanshi

Full Stack Software Developer, Experienced in Angular, Flutter, Spring boot, NodeJs, MySQL, MongoDB, AWS, Google Cloud, Docker, Git, JIRA.