Building a REST API using Spring Boot 2.0

Java is one of the most popular programming languages according to TIOBE index. Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. In this tutorial, we are going to use Spring boot to create a REST API.

0. Prerequisites

It’s important to install these tools:

  1. Java 1.8+
  2. Maven
  3. Postman
  4. Eclipse or any Java IDE (Optional)

1. Generate project

Let’s generate a seed project using the Spring Initializr. The most important part is the dependencies.

Now, click on “Generate Project” button.

Let’s open Eclipse and click on Import -> Existing maven Projects -> Browse and open the unzip project folder. Now use maven install to download dependencies.

2. Architecture

https://qiita.com/yu_eguchi/items/5bdda6f6ee7baf441870

Let’s explain the flow using this example:

GET — http://myapi.com/api/user/admin/login

The request go to the server using “http://myapi.com/”. Then the request arrives to the Spring Boot Application and using the route “/api/user/admin/login/”.

/controllers/UserController.java

In the second line, we can see the controller’s root route “/api/user” so the methods go to the UserController and match the route to a method using the RequestMapping annotation, in this case is the logIn method.

The controller calls the service, then the service calls the Data Access Object (DAO) to get data from the database. Most of the bussiness logic should be in the service.

/service/LibraryService.java

If the data needs any transformation, we do it in the service layer before send it to the DAO.

The DAO accesses to the database, executes a query and returns the database data.

/dao/UserDAO.java

The DAO returns a entitie or persistance object. The entitie or persistance is a representation of the database table in the Java project.

Then the service get the entitie and call the Data Transfer Object Builder(DTOBuilder) to convert the entitie into a Data Transfer Object (DTO).

/dto/ApiDTOBuilder.java

If there’s any transformation to do in the response, here is where we do it. The return of the DTOBuilder is taken by the service and the service sends it to the controller which finally returns the response.

3. Project structure

Project Structure

The project structure is based on the architecture that is exposed in the second section.

4. Configure database connection

In the src/main/resources there’s a file “application.properties”. This file has the spring configuration like the database connection.

#/src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/restDemo
spring.datasource.username: root
spring.datasource.password: root
spring.datasource.tomcat.max-active: 50

# If the database change, the only line that changes is the hibernate's dialect.
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=update
# Define a custom port instead of the default 8080
server.port = 8443

5. Create an entitie

Spring framework let us to create the Java object and then the framework will create the tables automatically in the database using the configuration in the application.properties.

/**
* /entities/User.java
**/
@Entity
@Table(name = "users")
@Inheritance(strategy = InheritanceType.JOINED)
public class User {
@Id
private String username;
 @Column(nullable = false)
private String password;
 @Column(nullable = false)
private int userType;
 @Column(nullable = false, unique = true)
private String email;
 @Column(nullable = false)
private String name;
 @Column(nullable = false)
private String lastName;
 private String tel;
 private Date bornDate;
}

All the annotations are from Java Persistence Annotation (JPA) which is a Java application programming interface specification that describes the management of relational data in applications using Java Platform, Standard Edition and Java Platform, Enterprise Edition.

6. Create a Data Access Object (DAO)

It’s a good practice separate the logic from the implementation, that’s why we are going to create an interface.

/**
* /dao/IUserDAO.java
*/
public interface IUserDAO {
public User getUser(String username);
}

Then, we implement the interface.

/**
* /dao/UserDAO.java
**/
@Repository
public class UserDAO implements IUserDAO {
@PersistenceContext
EntityManager em;
//Returns the User whose username is the parameter 'username'.
@Override
public User getUser(String username) {
// The find's method search a record using the primary key.
return em.find(User.class, username);
}
}

7. Create a Data Transfer Object (DTO)

The communication object between the service and the controller is the DTO so we create our DTO based on our persistence.

/**
* /dto/UserDTO.java
**/
public class UserDTO {
private String username;
private String password;
private int userType;
private String email;
private String name;
private String lastName;
private String tel;
private Date bornDate;
// Constructor, Getter, Setters
}

Now we create a DTOBuilder.

/**
* /dto/ApiDTOBuilder.java
**/
public class ApiDTOBuilder {
public static UserDTO userToUserDTO(User user) {
return new UserDTO(user.getUsername(), "", user.getUserType(),
user.getEmail(), user.getName(), user.getLastName(),
user.getTel(), user.getBornDate());
}
}

8. Create a service

As we did with the DAO, we create an interface with all the methods.

/**
* /service/IUserService.java
**/
public interface IUserService {
public UserDTO getUserByUsername(String username);
}

Then, we implement the interface

/**
* /service/ApiDTOBuilder.java
**/
@Component
public class UserService implements IUserService {
@Autowired
private IUserDAO userDAO;

@Override
public UserDTO getUserByUsername(String username) {
User user = userDAO.getUser(username);
return ApiDTOBuilder.userToUserDTO(user);
}
}

9. Create a controller

/**
* /controllers/UserController.java
**/
@RestController
@RequestMapping("/api/user")
@CrossOrigin
public class UserController {
@Autowired
UserService service;

@RequestMapping(value="{username}/login", method=RequestMethod.GET, produces="application/json" )
public ResponseEntity<UserDTO> logIn(@PathVariable String username) {
UserDTO user = service.getUserByUsername(username);
return new ResponseEntity<>(user, HttpStatus.OK);
}
}

The controller has 2 kind of routes:

  1. Root: This route is associated with the class. In our example is declared in the first RequestMapping annotation.
  2. Method route: This route is associated with an specific method and it’s declared with a requestMapping annotation in the method. In our example, “{username}/login” is our method route.

It’s important to note that there are 2 ways to pass data to a web service:

  1. Path Variable: The path variable is send in the url. In our example, “username” is our path variable and it’s declared in the RequestMapping annotation, so in this url: http://myapi.com/api/user/admin/login, the param is before the “/login”, in this case the username path variable is “admin”.
  2. Body: The body is available in POST and PUT services. GET and DELETE verbs don’t have a body. The body could be a JSON or an XML.

10. Test the API

We’re almost done, now let’s test our API. Open the terminal (Linux or MacOS) or powershell (Windows). Then go to the folder where is located the pom.xml and type this command.

mvn install

mvn install downloads all the dependencies and generate a jar file.

jose@jose-X550JX:~/Downloads/rest-demo$ mvn install
[INFO] Scanning for projects...
Downloading: https://repo.spring.io/milestone/org/springframework/data/spring-data-releasetrain/Kay-SR5/spring-data-releasetrain-Kay-SR5.pom
...
[INFO] Installing /home/jose/Downloads/rest-demo/target/rest-demo-0.0.1-SNAPSHOT.jar to /home/jose/.m2/repository/com/uis/rest-demo/0.0.1-SNAPSHOT/rest-demo-0.0.1-SNAPSHOT.jar
[INFO] Installing /home/jose/Downloads/rest-demo/pom.xml to /home/jose/.m2/repository/com/uis/rest-demo/0.0.1-SNAPSHOT/rest-demo-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.725 s
[INFO] Finished at: 2018-03-31T10:40:04-05:00
[INFO] Final Memory: 28M/278M
[INFO] ------------------------------------------------------------------------

Now we executes the jar using the following command:

java -jar /home/jose/.m2/repository/com/uis/rest-demo/0.0.1-SNAPSHOT/rest-demo-0.0.1-SNAPSHOT.jar
java -jar <jar-route> output

Now, let’s look at the final lines in the output:

2018-03-31 10:43:12.188  INFO 6720 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'dataSource' has been autodetected for JMX exposure
2018-03-31 10:43:12.193 INFO 6720 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2018-03-31 10:43:12.259 INFO 6720 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8443 (http) with context path ''
2018-03-31 10:43:12.263 INFO 6720 --- [ main] com.uis.restdemo.RestDemoApplication : Started RestDemoApplication in 4.35 seconds (JVM running for 4.713)

The most important part is the port, in this case our port is 8443. Now, let’s open postman and use the following url: http://localhost:8443/api/user/admin/login and send it.

Postman
Of course, it’s important to note that I inserted an user in the database to test the API.

The source code is published on https://github.com/JoseDRojasA/rest-demo.

Like what you read? Give Jose David Rojas Aguilar a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.