kotlin spring boot 7p

Kotlin meets Spring Boot – What’s in it for us?


Most of you might know Kotlin as a programming language designed for developing Android mobile applications. Since its first appearance in 2011, it has been challenging good old Java to a race for number 1 in the market. How big of a player it actually has become could be seen when Google announced that “the next big step that we’re taking is that we’re going Kotlin-first.” in May 2019.

Less famous is Kotlin’s use in backend applications. At SEVEN PRINCIPLES we took the opportunity to develop a new Spring Boot application and decided to give Kotlin a try. Read on for insights into features we loved about this symbiosis and issues we ran into. We will cover a brief compatibility check, data classes as DTOs, Kotlin’s null safety guarantees and the use of extension functions.


Kotlin: Compatibility

Kotlin natively runs on the JVM. That’s great! Because it allows us to use practically any library written in Java. This also holds true for the Spring framework.

class CoreApplication

fun main(args: Array<String>) {

Have a look at the Controller implementation in our code example. There is everything that you might already know from Java backend programming. Dependency injection still works by annotation-based wiring of Spring components.

class UserController(val userService: UserService) { 
    // List all users 
    fun readAll(@RequestParam("search") keyword: String? = null): List<UserDto> { 
        return userService.findAllFilteredBy(keyword).map { it.mapToDto() } 
    fun update(@RequestBody userDto: UserDto, @PathVariable("id", required = true) id: Long) { ... } 

Kotlin: Data Classes as DTOs

Data classes – as you have probably already guessed from their name – were designed for “holding data”. They ship with attribute accessors and come in handy for use as Data Transfer Objects (DTOs). DTOs should be kept free from business logic; they hide implementation details from the “world wild web” and prevent unintended manipulation of your application’s state. As you can see in our code example, that is exactly what data classes do. You can get rid of Java’s extensive getters and setters by simply declaring mutable “vars” and immutable “vals” in Kotlin’s primary class constructor. Slick, eh?

data class UserDto(
    val firstName: String?,
    val lastName: String,
    val dateOfBirth: Date?
class UserController(val userService: UserService) {
    // List all users
    fun readAll(@RequestParam("search") keyword: String? = null): List<UserDto> { ... }

    fun update(@RequestBody userDto: UserDto, @PathVariable("id", required = true) id: Long) {
        val (firstName, lastName, dateOfBirth) = userDto
        val user = userService.findById(id) ?: throw RuntimeException("No user found for id $id.")

        userService.update(user, firstName, lastName)

Small hint: Initialization of multiple variables at once with values from a data class instance makes use of “Destructuring components” and can really brighten up your day.

Kotlin: Null Safety

APIs have a huge source of uncertainty – namely the user. Whenever there is variable input into our application, input validation is needed. Kotlin has a great way of easing this task for us. As shown in the code snippet above, you must explicitly allow nullable values by denoting the corresponding variable type with a “?”. What happens if we try to send a request to our update method with an empty “lastName” attribute? It would be rejected with Http-Status “404 – Bad Request”. What happens if we try to call a function which expects a non-null value parameter with a nullable variable? The code will simply not compile. Bye bye, NullPointerExceptions! Attention should be paid when calling Java code. The Kotlin compiler uses assertions for this. But that does not prevent NPEs being thrown if the actual runtime object references a null value.

Do you like Rock ‘n’ Roll? Kotlin has it. Did you notice the “?:”-statement in the code example below? That is the so called “Elvis Operator”. It reads as “If A is null assign B”. We did happily use it for variable initialization and invoking exceptions as seen previously. When applied to a variable the Kotlin compiler automatically recognizes the corresponding value as non-null from then on.

class UserService(val userRepository: UserRepository) {
    fun findAllFilteredBy(keyword: String?): List<User> { ... }

    fun findById(id: Long): User? { ... }

    fun update(user: User, firstName: String?, lastName: String) {
        user.firstName = firstName ?: user.firstName
        user.lastName = lastName


Kotlin: Extension Functions

Extension functions allow augmenting the behavior of existing classes for which modifying the original class signature is not possible – as in the case of third-party libraries. If you tried to find an analogue in the Java world, they are basically member functions declared outside of the regular class definition. We have used extension functions for wrapping data from our business logic objects into the DTOs used for the transport layer of our application.

fun User.mapToDto(): UserDto {
    return UserDto(

Kotlin: Function Declaration

A word of warning: Without a mutual understanding for the application of extension functions their extensive use could lead to confusion; especially when collaborating in a larger team.

fun User.functionHiddenSomewhereOutOfScope(input: Any) {
    this.firstName = ""
    this.lastName = ""

Note how Kotlin allows different ways of function declaration in the code example below. Although this results in shorter code and better readability, without IDE support it is not always directly clear what the return value or purpose of the function is.

fun surpriseMe(input: Any) = input.prepareGift()

fun anythingIsAppreciated(input: Any): Any = input.prepareGift()

fun butILikeItExplicit(input: Any): Any {
    return input.prepareGift()

Kotlin: Conclusion

For the sake of brevity this article does not cover everything we delved into. All in all, we agreed that – after a time of adapting – writing Kotlin felt pretty natural and its syntax blends in neatly with Spring Boot. It simplifies many things that should have been simple from the start, but were not simple in Java, e.g. wrapping of objects and input validation. Not every feature that ships with Kotlin can yet be exploited in the context of Spring Boot. In our case, we ran into issues when it came to reactive programming and the implementation of JPA with Hibernate. If you feel tempted to gather more impressions, try the sources below for further reading.







2 Kommentare

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.