A basic understanding of HTTP requests and CRUD is needed to complete this tutorial. The github link can be found here for this project.

Kotlin is one of the most sought-after programming languages in both the mobile and web development ecosystem. It can be used as an alternative to Java for both Android development and Java web development because it runs on the JVM and is interoperable with Java APIs. In this tutorial, we will go over how to build a REST API using Kotlin and Spring Boot 2.

In order to get started with our project, we must first use the Spring Boot Initializer. You can either use the one at https://start.spring.io/ or the one built into IntelliJ IDEA.

Spring Boot Init Web

Spring Boot Init Web

Spring Boo Init IntelliJ

Spring Boo Init IntelliJ

We will select our dependencies in order to allow for Restful routing, database persistence and database migrations.

Spring Boot Dependency Select

Spring Boot Dependency Select

Inside of your gradle.build file, verify that the correct dependencies have been installed.

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('com.fasterxml.jackson.module:jackson-module-kotlin')
    compile('org.flywaydb:flyway-core')
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    compile("org.jetbrains.kotlin:kotlin-reflect")
    runtime('org.postgresql:postgresql')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Application Startup – Setting Up Migrations

The starting point for our application is in our TodolistapiApplication.kt file. Under the todolistapi folder, we will want to create another folder called todo as well as a class file called Todo.kt. When setting the ID of the todo, it is important that you use GenerationType.IDENTITY instead of GenerationType.AUTO because PostgreSQL uses Sequence tables instead of Auto-Increment

package com.example.kotlintodo.todo

import com.example.kotlintodo.core.BaseEntity
import javax.persistence.*

@Entity
@Table(name = "todo")
class Todo {

    /* GenerationType.IDENTITY is for databases like Postgres
        that use sequence tables instead of auto-increment
     */
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition = "serial") var id: Long? = null

    var title: String? = null
    var description: String? = null
    var finished: Boolean? = false


}

Now that we have our model setup, now we have to create our migration.

Inside of our main/resources folder, create a db/migration folder. Create a migration SQL file for the database named V1__Create_todo_table.sql

CREATE TABLE todo(
  ID SERIAL PRIMARY KEY NOT NULL,
  TITLE       VARCHAR(255),
  DESCRIPTION TEXT,
  FINISHED BOOLEAN NOT NULL
);

Now, inside of your build.gradle file add the flyway migration configuration

flyway {
	url = 'jdbc:postgresql://localhost:5432/springtodo'
	user = 'postgres'
	password = ''
	outOfOrder = true
}

Now run the gradle command to create the migration.

gradle flywayMigrate -Dflyway.url=... -Dflyway.user=... -Dflyway.password=...

SETTING UP RESTFUL Controllers

Now that we have our migrations up and running, we have to find a way to get objects in and out of the database. We’ll need both a repository for our CRUD actions as well as a controller for receiving HTTP requests.

First let’s start off by creating a TodoRepository.kt file in our todo package.

package com.example.kotlintodo.todo

import org.springframework.data.jpa.repository.JpaRepository

interface TodoRepository : JpaRepository<Todo, Long>

This Repository is a Kotlin interface that inherits from JpaRepository. Under the hood, it uses Hibernate to map database queries to our database provider, PostgreSQL

Now that we have that, we can now create our controller. Create a new package called controller and place in a TodoRestController.kt Kotlin file

package com.example.kotlintodo.controller

import com.example.kotlintodo.todo.Todo
import com.example.kotlintodo.todo.TodoRepository
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.*
import java.util.*

@RestController
@RequestMapping("/todos")
class TodoRestController(val todoRepository: TodoRepository) {

    @GetMapping
    fun getTodos() = todoRepository.findAll()

    @RequestMapping(path = [("/{todoId}")], method = [(RequestMethod.GET)])
    fun getTodo(@PathVariable("todoId") todoId: Long?): Optional<Todo>? {
        return todoRepository.findById(todoId)
    }

    @PostMapping
    fun newTodo(@RequestBody todo: Todo): Todo {
        todoRepository.save(todo)
        return todo
    }

    @PutMapping
    @ResponseStatus(HttpStatus.OK)
    fun updateTodo(todo: Todo) {
        todoRepository.save(todo)
    }

    @RequestMapping(path = [("/{todoId}")], method = [(RequestMethod.DELETE)])
    fun deleteTodo(@PathVariable("todoId") todoId: Long?) {
        todoRepository.deleteById(todoId)
    }
}

Here we pass in an instance of our repository and make the respective calls based on the CRUD action. We also use Kotlin annotations each controller method to with the type of request that method will receive.

Now you should be able to run the application, create, view and delete your todos.

Create Todo

Create Todo

List Todos

List Todos

Conclusion

As the industry moves forward, there will be a larger shift away from Java toward Kotlin because of the concise syntax and the decreased amount of boilerplate. With both in the ability to operate with both Android and Spring Boot as well as directly call Java APIs, it will ease the pain of migrating older codebases.

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit