Building an Application with Kotlin Spring Boot / Spring Framework

This guide is meant to give you a quick taste of Kotlin and Spring Boot. you want to create your own Spring Boot-based project, visit Spring Initializr, fill in your project details, pick your options, and download a bundled up project as a zip file.

What You Will build

You will build a simple web application with Kotlin Spring Boot and add some useful services to it.

What You Need

Starting with Spring Initializr

To manually initialize the project:

  1. Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you.
  2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Kotlin.
  3. Click Dependencies and select Spring Web and Spring Data JPA and choose one of your database driver:
    • PostgreSQL Driver (this guide is using this)
    • MariaDB Driver
    • MySQL Driver
  4. Click Generate.
  5. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
kotlin-spring-1

Project Installation

  1. Unzip it and open with IntelliJ IDEA
  2. Ensure your Project Structure in Intellij is using Java 21
kotlin-spring-2
  1. Ensure your setting Kotlin to JVM is using JVM 21
kotlin-spring-3
  1. Please wait for a few minutes or seconds. Intellij will download all the project dependencies.
  2. Check your intellij looks ready to run with play button like below.
kotlin-spring-4
  1. Create table in your postgresql database
CREATE TABLE student (
    id SERIAL PRIMARY KEY,
    full_name VARCHAR(255),
    nick_name VARCHAR(255),
    email VARCHAR(255),
    address VARCHAR(255),
    city VARCHAR(255),
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    created_by VARCHAR(255) NOT NULL,
  	updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
  	updated_by VARCHAR(255) NOT NULL
);

Create a Simple Web Application

in your pom.xml add this dependency

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.8.4</version>
   </dependency>
   <dependency>
      <groupId>com.fasterxml.jackson.module</groupId>
      <artifactId>jackson-module-kotlin</artifactId>
   </dependency>

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
  </dependency>

or add this dependency in your build.gradle

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.4'
implementation 'org.springframework.boot:spring-boot-starter-validation'

and then you can install it using mvn install or gradle build.

or using intellij click this button
using maven

kotlin-spring-5

using gradle

kotlin-spring-6

now setup your application.properties

spring.datasource.url=jdbc:postgresql://localhost:5432/<YOUR_DATABASE_NAME>?currentSchema=<SCHEMA_NAME>
spring.datasource.username=<YOUR_USERNAME>
spring.datasource.password=<YOUR_PASSWORD>
spring.datasource.driver-class-name=org.postgresql.Driver

spring.datasource.hikari.minimum-idle=2
spring.datasource.hikari.maximum-pool-size=3

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

# if you have been using postman for interacting with API, this is an alternative
# https://springdoc.org/
springdoc.swagger-ui.enabled=true
springdoc.api-docs.enabled=true

Now you can create a web controller for a simple web application, as the following listing (from src/main/kotlin/com/example/springkotlin/StudentController.kt) shows:

@RestController
class StudentController {

	@GetMapping("/student-list")
	fun getAllStudent(): String {
		return "Greetings from Kotlin Spring Boot!"
	}

}

Click the play button here (SpringkotlinApplication.kt)

kotlin-spring-7

and should be running well like this

kotlin-spring-8

and you can see this message in your console or terminal

2025-02-02T10:02:43.546+07:00  INFO 26741 --- [springkotlin] [  restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-02-02T10:02:43.568+07:00  INFO 26741 --- [springkotlin] [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-02-02T10:02:43.820+07:00  WARN 26741 --- [springkotlin] [  restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-02-02T10:02:44.712+07:00  INFO 26741 --- [springkotlin] [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2025-02-02T10:02:44.736+07:00  INFO 26741 --- [springkotlin] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-02-02T10:02:44.747+07:00  INFO 26741 --- [springkotlin] [  restartedMain] c.e.s.SpringkotlinApplicationKt          : Started SpringkotlinApplicationKt in 6.598 seconds (process running for 7.741)

Go to here http://localhost:8080/swagger-ui/index.html and you should see like this

kotlin-spring-9

and you can use this swagger ui as your API documentation and interact with your API
click button Try it out

kotlin-spring-10

click button Execute

kotlin-spring-11

the result are like this (see the response body)

kotlin-spring-12

Create Entity and JPA Repository

Now you can create a entity, as the following listing (from src/main/kotlin/com/example/springkotlin/StudentData.kt) shows:

@Entity
@Table(name = "student")
data class StudentData (

    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    @Column(name = "id")
    val id: Int? = null,

    @Column(name = "full_name")
    val fullName: String?,

    @Column(name = "nick_name")
    val nickName: String?,

    @Column(name = "email")
    val email: String?,

    @Column(name = "address")
    val address: String?,

    @Column(name = "city")
    val city: String?,

    @CreationTimestamp
    @Column(name = "created_at")
    val createdAt: OffsetDateTime? = null,

    @Column(name = "created_by")
    val createdBy: String?,

    @UpdateTimestamp
    @Column(name = "updated_at")
    val updatedAt: OffsetDateTime? = null,

    @Column(name = "updated_by")
    val updatedBy: String?,
)

Now you can create a repository, as the following listing (from src/main/kotlin/com/example/springkotlin/StudentDataRepository.kt) shows:

@Repository
interface StudentDataRepository : JpaRepository<StudentData, Int> {

    fun findByEmail(email: String?): List<StudentData>?

}

and create the DTO for create student request body

@JsonIgnoreProperties(ignoreUnknown = true)
data class CreateStudentRequest (
    @field:NotNull
    @field:NotBlank
    val fullName: String?,

    @field:NotNull
    @field:NotBlank
    val nickName: String?,

    @field:NotNull
    @field:NotBlank
    val email: String?,

    @field:NotNull
    @field:NotBlank
    val address: String?,

    @field:NotNull
    @field:NotBlank
    val city: String?
)

and create a configuration class (src/main/kotlin/com/example/springkotlin/config/AppConfig.kt)

@Configuration
class AppConfig {

    @Bean
    fun validator(): LocalValidatorFactoryBean {
        return LocalValidatorFactoryBean()
    }

}

Let's update the controller code

@RestController
class StudentController @Autowired constructor(
    private val studentDataRepository: StudentDataRepository
) {

    @GetMapping("/student-list")
    fun getAllStudent(): List<StudentData> {
        return studentDataRepository.findAll()
    }

    @GetMapping("/student/{studentId}")
    fun getStudentById(@PathVariable studentId: Int): StudentData? {
        return studentDataRepository.findById(studentId).orElse(null)
    }

    @GetMapping("/student")
    fun getStudentByEmail(@RequestParam email: String): List<StudentData>? {
        return studentDataRepository.findByEmail(email);
    }

    @PostMapping("/student")
    fun createStudent(@Valid @RequestBody request: CreateStudentRequest): StudentData? {
        val studentData = StudentData(
            fullName = request.fullName, 
            nickName = request.nickName,
            email = request.email,
            address = request.address,
            city = request.city,
            createdAt = OffsetDateTime.now(),
            createdBy = "admin",
            updatedAt = OffsetDateTime.now(),
            updatedBy = "admin"
        )

        return studentDataRepository.saveAndFlush(studentData);
    }
}

and re run the app by click the play button.

now open again your swagger-ui and expand the POST /student and execute it

kotlin-spring-13 kotlin-spring-14 kotlin-spring-15

and then use the GET /student/{studentId}

kotlin-spring-16

and then use the GET /student?email=string

kotlin-spring-17

and then use the GET /student-list

kotlin-spring-18

Summary

Congratulations! You have just developed a Kotlin Spring application that is bound to a PostgreSQL database and is ready to use! And you have taste in how to develop REST API Spring Boot applications.

I hope you are now understand how to use Kotlin Spring Boot to create REST API Service.
Thank you for reading and your attention. See you soon on the next post.

Challenge

I'm giving you to challenge to explore more about Kotlin Spring

  1. you can use ResponseEntity in your StudentController you can use ResponseEntity in kotlin like code snippet below
@GetMapping("/student-list")
fun getAllStudent(): ResponseEntity<List<StudentData>> {
    val result = studentDataRepository.findAll();
    return ResponseEntity.ok(result)
}

If you want to see the codebase please visit this GitHub: kotlin-spring-introduction

Learn more

Go learn more about