Build RESTful Services with Spring Boot 2.X in Few Steps

Matt Zhang
6 min readNov 25, 2018

--

Photo by Dlanor S on Unsplash

Spring Boot is built on top of Spring framework. With zero or minimum customization, it significantly reduces the efforts to develop Spring-based and production-grade applications by doing the heavy lifting of auto-configuration and dependency management under the hood. As a result, developers are able to genuinely focus on business-centric features.

This story is going to demonstrate how we build the RESTful services with Spring Boot in few steps. We will create a simple customer service to CRUD(a.k.a. create, read, update, delete) the customer records and banking accounts each customer has.

Table of Contents

Spring Initializr

Spring Initializr is the first stop along the unfolded journey of Spring Boot. Its used to create Spring Boot application with consistent project structure. Before Spring Boot, we need to figure out the project structure and decide where to keep the configuration files, property files, and the static files so forth. Having worked in different projects in the past, I’ve seen similar java projects with varying project structure. Let's open the web-based interface to start. Fill in the fields as the following screenshot shows and click ‘Generate Project’ button.

  • Group: com.codespeaks.rest
  • Artifact: customerservice
  • Name: customerservice
  • Package Name: com.codespeaks.rest.customerservice
  • Dependencies: Web, JPA, H2
Spring Initializr to create a project
Project structure

The POM file as follows denotes dependencies of the starter project. In Spring Boot, different starter project is representing different Spring module such as MVC, ORM etc. What developers mostly do is to add the starter project in the dependencies, Spring Boot will manage the transitive dependencies and versions.

if we run mvnw dependency:tree command, the underlying dependency hierarchy will show as follows

Application Properties

We use the YAML (Yet Another Markup Language) based property file to define the configuration properties as its more readable than application.properties.

  • spring:application:name=customer-service # application name
  • spring:h2:console:enabled=true # enable embedded h2 console. We are using the in-memory database.
    spring:h2:console:path=/h2-console # Path at which the h2 console is available, we will use h2 console to check in memory data later on.
  • spring:jpa:show-sql=true # enable logging of SQL statements.
  • server:port=8080 # Server HTTP port.
  • server:servlet:context-path=/restapi # the base URL of the RESTful services

Domain Entities

In this example, we define JPA entities to showcase the following ER diagram where Customer entity holds one to many relationship with Account entity. Account.CustomerId is the foreign key referring to Customer.CustomerId.

ER diagram

The classes are denoted as the JPA entities with the following annotations

  • @Entity denotes the class is an entity.
  • @Table denotes the database table to which this entity is mapping.
  • @Id denotes the primary key of the entity
  • @GeneratedValue denotes the strategy of generating the primary key, the default strategy is the AUTO strategy.
  • @Column denotes the column mapping of entity attribute.
  • @ManyToOne denotes many to one relationship from Account to Customer. This relationship is specified on the child entity Accountin this example. We are not defining a bi-directional relationship by using@OneToMany annotation on relationship parent Customer side as the pagination will be a problem should we retrieve the accounts from Customer entity.
  • @JoinColumn denotes the foreign key column
  • @OnDelete denotes the cascade delete action in this example. When Customer entity gets deleted, all its accounts will be removed at the same time.
  • @JsonIgnore denotes the property to be ignored by JSON parser during serialization end deserialization.

Repositories

Spring Data JPA abstracts the persistence layer on top of the relational database and significantly decreases the amount of boilerplate code on CRUD operations and pagination. By extending the JPARepository interface which has to be typed with JPA entity and its primary key type, Spring Data will detect the interface and create implementation automatically at runtime. The CRUD methods that become readily available from inheritance cover most of data access use cases out of the box.

With JPARepository, we can also create custom queries by defining the interface methods. Spring Data JPA derives the query from the method name and implement the query logic at runtime. The followingfindByCustomerCustomerId method accepts the argument pageable that is of type Pageable and returns Page object typed with Accountclass. This is all regarding the pagination and will be demonstrated in the demo.

RESTful Controllers

The controller annotated with @Controller annotation in Spring MVC (Model-View-Controller) incorporates the business logic and controls the data flow between the model and view. The controller methods in most cases return ModelAndView object in order to render the view. But sometimes the value returned from controller methods is displayed to users in the format of JSON/XML instead of HTML page. To make this happen, annotation @ResponseBody comes into play and automatically serialize the returned value into JSON/XML which later is saved into the HTTP response body. The annotation @RestController combines the proceeding annotations and offers more convenience to create RESTful controllers.

The annotations @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping are more HTTP request specific than its predecessor @RequestMapping which needs to denote the HTTP request method bymethod variable separately.

ResponseEntity is used in some of the RESTful controller methods to represent the whole response which includes status code, headers, and response body. Unlike the @ReponseBody annotation which only populates the response body in the HTTP response, it gives us more freedom to manipulate the whole HTTP response.

Here are the two controller classes for Customer and Account related operations respectively.

In preceding controller classes, we defined a bunch of RESTful URIs as follows to operate with the resource Customer and Account.

  • /customers HTTP Get # Get all customers
  • /customers HTTP Post # Create a new customer
  • /customers/{customerId} HTTP Get # Get a customer
  • /customers/{customerId} HTTP Delete # Delete a customer
  • /customers/{customerId} HTTP Put # Update an existing customer
  • /customers/{customerId}/accounts HTTP Post #Create an account for a customer
  • /customers/{customerId}/accounts HTTP Get #Get accounts from a customer
  • /customers/{customerId}/accounts/{accountId} HTTP Delete # Delete an account from a customer
  • /customers/{customerId}/accounts/{accountId} HTTP Put # Update an account from a customer

In regards to the RESTful API design guidelines, it goes beyond the scope of this article. There are some good articles out there on the internet, check here and here.

Demo

The RESTful service examples can be found on Github. If you are not comfortable with Linux curl command, we can use Postman to call the RESTful services by simply importing the Postman collection file.

To check the data in the database, we can access H2 console via http://localhost:8088/restapi/h2-console/ with the details given below.

Driver Class:  org.h2.Driver
JDBC URL: jdbc:h2:mem:testdb
User Name: sa
Password: <blank>
H2 console login page
H2 console main page

Conclusion

Spring Boot is not competing with the Spring framework. Quite on the contrary, it makes Spring easier to use. With starter projects, Spring Boot manages the dependencies and frees us from time consuming and error-prone dependency management especially when the application complexity increases. Also, Spring Boot does the auto-configuration for us by checking the classpath. If the JPA implementation, for example, is present in the classpath, the DataSource, TransactionManager, and EntityManagerFactory etc will be configured by Spring Boot. At the same time, overriding the configuration Spring Boot does for us is straightforward and easy to implement.

All code can be found on GitHub

--

--

Matt Zhang

Living in Melbourne Australia. More than 10 years experience in Java development. Find me @ www.linkedin.com/in/lihui-matt-zhang-48408a37/