DEV Community

Cover image for Build REST API with Spring Boot and Kotlin
Anirban
Anirban

Posted on • Originally published at theanirban.dev on

Build REST API with Spring Boot and Kotlin

1. Overview

In this article, we're going to build a REST API using Spring Boot 2.x and Kotlin. Meanwhile, dedicated support for Kotlin was introduced since Spring Framework 5.0. We can read about the supported features in the official Spring Framework documentation.

In particular, the application will expose data via a REST API and persist data in an embedded H2 database.

2. Use Case

We'll build Restful APIs for an employee information application. A user can create, retrieve, update and delete an employee using this application. An employee has an id, username, first name, last name, email id, and date of birth. Moreover, the username of an employee must be unique.

We'll use an embedded H2 database as our data source along with JPA and Hibernate to access the data from the database.

3. Setup

We can use the Spring Initializer tool to create a Spring Boot application. Besides, we can read about the other ways that we can create a Spring Boot project in the blog post.

Subsequently, we will add Spring Web, Spring Data JPA, H2 Database, Spring Boot Devtools as the dependencies. So now we have all the basic dependencies in the build.gradle.kts that will allow us to work with Spring Boot and Kotlin:

The Gradle build file also contains some essential plugins:

  • The kotlin-spring compiler plugin is a wrapper on top of the all-open plugin. The all-open compiler plugin ensures that the Kotlin classes are annotated and their members are open. This makes it convenient to use libraries such as Spring AOP that require classes to be open unlike Kotlin classes and their members which are final by default.
  • The kotlin-jpa compiler plugin is a wrapper on top of the no-arg plugin. The no-arg compiler plugin generates a no-argument constructor for classes annotated with Entity, MappedSuperclass, and Embeddable. This ensures that JPA (Java Persistence API) can instantiate the class since it expects a no-argument constructor defined for its entities.

3.1. Configure Database

We have to configure the H2 database properties so that Spring Boot can create a data source. To define such properties, we can use an external configuration. Furthermore, we can define such external configuration using properties files, YAML files, environment variables, and command-line arguments.

In general, Spring Boot provides the application.properties file to define such database properties by default. The properties file uses a key-value format.

Alternatively, we can use YAML-based configuration files which use hierarchical data. The YAML files significantly help to avoid repeated prefixes and make is more readable compared to the properties file:

We can also use the application.yml file to define hibernate properties:

  • We set the ddl-auto property to update. It will update the database schema based on the modifications in the domain model in our application. This default value is create-drop if we use an embedded database without any schema manager. In case we're using a schema manager such as Liquibase or Flyway, we should consider using validate. It tries to validate the database schema according to the entities that we have created in the application and throws an error if the schema doesn’t match the entity specifications.
  • The show-sql property enables logging of SQL statement.
  • The generate-ddl property ensures whether to initialize the schema on startup.
  • The dialect property ensures that Hibernate generates better SQL for the chosen database.

4. Domain Model - Kotlin Data class

The domain model is the core part of the application. We can create a domain model Employee using a data class.

In addition, a data class in Kotlin automatically generates equals/hashCode pair, toString, and copy functions. Besides, We don't need to define getter and setter methods like Java:

  • The @Entity annotation specifies that the class is an entity and mapped to a database table.
  • The @Table annotation specifies the name of the database table that is used for mapping. If we use the @Table annotation without a table name, then Spring generates the table name from the class name.
  • The @Id annotation specifies the property which is the primary key in the entity class.
  • The @GeneratedValue annotation specifies the generation strategies for the values of the primary keys.
  • The @Column annotation specifies the mapped column for a persistent property. If we do not use the @Column annotation, then Spring generates the column name from the property name.

5. Repository

We're going to create a repository interface to interact with the database. Moreover, the EmployeeRepository interface will extend from the JpaRepository interface. This ensures that all the CRUD methods on the Employee entity are available:

  • The @Repository annotation specifies that the class is a repository and represents the data access layer in our application.

6. Service

Now, we're going to create a service class that will provide the business logic. Besides, the service layer can interact with the data access layer using JPA.

We inject an instance of the EmployeeRepository via constructor in EmployeeService:

  • The @Service annotation specifies that the class is a service.
  • The getAllEmployees() function can fetch a list of all employees.
  • The getEmployeesById() function can fetch one employee based on the id. We provide the employee id as a parameter to the function.
  • The createEmployee() function can create a new employee. We provide the required properties of the new employee as a parameter to the function.
  • The updateEmployeeById() function can update the employee details based on the id. We provide both the employee id and the properties as parameters to the function.
  • The deleteEmployeesById() function can delete an employee based on the id. We provide the employee id as a parameter to the function.

7. Controller

We implement the APIs for all the CRUD operations in the controller layer which invokes the underlying service.

We define a EmployeeController as our controller class. In particular, it's a REST controller that provides endpoints for creating, manipulating, and deleting employees.

The EmployeeService class is wired into the controller to return the values. Also, we reuse the entities as data transfer object for simplicity:

The @RestController annotation specifies that the class is a controller and capable of handling requests. It combines both the @Controller and @ResponseBody annotations.

Spring provides several annotations to handle the different incoming HTTP requests like GET, POST, PUT and DELETE. These annotations are @GetMapping,@PostMapping,@PutMapping, and @DeleteMapping.

8. Running the application

We can run the application using the following command in the terminal:

gradle bootRun
Enter fullscreen mode Exit fullscreen mode

The Spring Boot application will start running at http://localhost:8080.

9. Exploring the APIs

9.1. Create an Employee

We send the following request to create an employee:

We receive the following response in JSON format:

9.2. Get All Employees

We send the following request to fetch all employees:

We receive the following response in JSON format:

9.3. Get an Employee

We send the following request to fetch an employee based on the employee id:

We receive the following response in JSON format:

9.4. Update an Employee

We send the following request to update employee properties based on the employee id:

We receive the following response in JSON format:

9.5. Delete an Employee

We send the following request to delete an employee based on the employee id:

10. Conclusion

In this tutorial, we looked into creating a microservice application and expose REST API using Kotlin and Spring Boot. In the process, I have also used some best practices which we can utilize while building such applications.

The code for these examples is available on GitHub.

To learn more, check out the related articles on Spring Boot.

Originally published on Anirban's Tech Blog.

Top comments (0)