How to Build a Spring Boot REST API with Java ?

İbrahim Aktan Sanhal
Codimis
Published in
8 min readOct 20, 2022

In this article, we want to learn how to build a REST API using Spring Boot. First, we will understand the use case and requirements, then we will implement the layers.

Step 1 — We will use simple free tool to help us draw our database relationship diagrams.

Step 2 — We will define our entity classes.

Step 3 — We will create repositories that returns the response for the services.

Step 4 — We will create our service classes and define implementations.

Step 5 — We will create controllers and complete our layers.

Getting Started

Let us learn how to use Spring Initializr to generate the Spring Boot project for which the first step is navigating to start.spring.io to get it.

Let’s learn a bit about the dependencies that we selected for our new project

Spring Web

It is used for building web applications that include RESTful applications. It has an embedded container called Tomcat.

Spring Boot DevTools

Spring-boot-devtools module includes an embedded Live Reload server that can be used to trigger a browser refresh when a resource is changed.

Spring Data JPA

Spring Data JPA aims to significantly improve the implementation of data access layers by reducing the effort to the amount that’s actually needed. As a developer, you write your repository interfaces, including custom finder methods, and Spring will provide the implementation automatically.

MySQL Driver

This dependency offers us the ability to connect to the database.

Lombok

Lombok provides us with a collection of annotations that eases some boring java steps(getters and setters creation).

The fastest way to start a spring boot project.

In the project, we will use Maven. For language, select Java, and complete the basic details about the project name, artifact name, and other blanks. Click Generate and follow the steps below.

Open the project. You will see something like below.

Now, we should define the URL for our database connection. Open the application.properties file. We will set the configuration to autocreate the schema for our project. We will tell Hibernate that we want to update the schema on each run by Setting hibernate.ddl-auto to update.

  1. Open your MySQL Workbench
  2. Click to create schema
  3. Define your schema name
  4. Click apply to create your scheme

Our Database Diagram

We have three models to apply. We will take the Many-to-One relationship to use for our project.

@ManyToOne and @OneToMany Relationships

ManyToOne and OneToMany mappings mean that one row in a table is mapped to multiple rows in another table.

Implementing Entities

After we have defined the database, we can start implementing entity classes. The entity class provides a direct connection to the table in the database.

Why Do We Create Entity Classes ?

Entities are persistence objects stored as records in the database. A set of entity classes represents the data contained within a single data store.

We will create User, Post and Comment model classes to map with the defined tables.

@Entity is used to annotate that class is an entity in our database.

@Table is used to annotate the name of table in our database.

@GeneratedValue is used to generate strategies for the values of primary keys.

@Id annotation is indicating the member field is the primary key of the current entity.

@OnDelete in hibernate is used when there are joined sub class.

@JoinColumn annotation combined with a @OneToOne mapping indicates that a given column in the owner entity refers to a primary key in the reference entity

@Lob annotation is used to specify that the currently annotated entity attribute represents a large object type.

@JsonIgnore is used to tell Jackson to ignore a certain field of a Java object. The field is ignored both when reading JSON into Java objects, and when writing Java objects into JSON.

User

We have id, name, and password fields for the user entity. Let’s make these definitions.

Post

We have id, user, title, text fields for the post entity. We map the user with user_id which is represent our database field.

Comment

We have id, post, user, and text fields for the comment entity. We write the same mapping process for the User and Post fields and connect them with user_id and post_id.

Creating Repositories

After creating entities, we start developing the data access layer. The data access layer allows us to use methods to manipulate the data in our database. We will build a data access layer as the repository pattern.

JPA Repository is a particularly JPA-specific extension for Repository. It has full API CrudRepository and PagingAndSortingRepository. Briefly, Jpa Repository contains the APIs for primary CRUD operations.

Important Tip!

Before business layer, we want to create new @Data Classes . Because, in Post and Comment classes, we defined userId and postId fields as User and Post objects. I want to get these fields from client as Long Type. At the same time, I restrict the user by requesting the fields in this way (for update requests).

The business layer includes business logic. It contains code for the requirement. Each service class has its own business logic for application.

Building the Business Layer

Constructor Injection

We use constructor injection when we want to inject dependencies using an object constructor. This type of injection is safer as the objects won’t get created if the dependencies aren’t available or dependencies cannot be resolved.

Business(Service) Layer

Business layers have their own business logic. It defines which functionalities you provide, how they are accessed, and what to pass and get in return.

User Service

Post Service

Comment Service

Building Controllers

After creating entities, we start to create our controllers that solve the requirement that the application should be accessible through the browser. Our spring-boot-starter-web dependency contains everything that we need about controller. We will define a controller using @RestController Annotation so we can handle our all requests.

Required Annotations

@GetMapping Annotation

@GetMapping annotation is a specialized version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod. GET) .

@PostMapping Annotation

@PostMapping is a specialized version of @RequestMapping annotation that acts as a shortcut for @RequestMapping(method = RequestMethod. POST) .

@PutMapping Annotation

@PutMapping annotation is used for mapping put requests onto specific handler methods.@PutMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PUT).

@DeleteMapping Annotation

@DeleteMapping annotation maps delete requests onto unique handler methods. It is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod. DELETE) .

@RequestMapping Annotation

RequestMapping annotation is used to map requests onto specific handler classes. @RequestMapping can be applied to the controller class as well as methods.

@PathVariable Annotation

@PathVariable is a Spring annotation that indicates that a method parameter should be bound to a URI template variable. It has the following optional elements: name — name of the path variable to bind to. required — tells whether the path variable is required. value — alias for name.

@RequestParam Annotion

@RequestParam is a Spring annotation used to bind a request parameter to a method parameter. It has the following optional elements: defaultValue — used as a fallback when the request parameter is not provided or has an empty value. name — name of the request parameter to bind to.

@RequestBody Annotation

@RequestBody annotation maps the request body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.

User Controller

Click to copy code

@RequestMapping(“/users”) annotation maps bean to this path. When we start the application locally we can see the endpoint on the http://localhost:8080/users .

We wrote getAllUsers() method using @GetMapping Annotation to define this is the Get method. Since we didn’t define an additional path on the @GetMapping Annotation we are using the path from the @RequestMapping Annotion definitions.

@PostMapping defines that this method is post and that we want to create a new resource through it.

Post Controller

Click to copy code

@RequestBody annotation shows that we are expecting data inside the http requests body.

Comment Controller

Click copy to code

We used @PutMapping annotation for define which resource we want to update. Endpoint looks like: http://localhost:8080/comments/{commentId}.

Id variable is called the path variable and we can pass it into the method using @PathVariable annotation on the method argument.value inside @PathVariable need to match with value inside @PutMapping.

We used @DeleteMapping(“/{commentId}) for define which resource we want to delete. We can see that the path is the same as in the put endpoint but the HTTP method is different. The paths have to be unique for the same http method.

References

--

--