paint-brush
Kotlin-Spring Boot: Gotchasby@gokulc
5,939 reads
5,939 reads

Kotlin-Spring Boot: Gotchas

by Gokul Chandrasekaran3mDecember 25th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

It’s been around 6 months since we adopted Kotlin for our backend services at the company I currently work at. We’ve been migrating an existing java spring boot service to Kotlin.

Company Mentioned

Mention Thumbnail
featured image - Kotlin-Spring Boot: Gotchas
Gokul Chandrasekaran HackerNoon profile picture

It’s been around 6 months since we adopted Kotlin for our backend services at the company I currently work at. We’ve been migrating an existing java spring boot service to Kotlin.

Our experience with Kotlin has been mostly great. But sometimes it does feel like Spring was retrofitted to support Kotlin.There’s the basic issues like :

  1. Spring requires classes with annotations to be open, all classes in Kotlin are closed by default. This can be resolved by adding the **kotlin-spring** plugin to the gradle config.
  2. Hibernate entities require a no-arg constructor, Kotlin has provided a compiler plugin **kotlin-jpa** to generate an additional zero-argument constructor for classes.

It is important to note that these issues have been identified and the project is generated using start.spring.io have these plugins baked into your configuration. More details on this in the Further Reading section.

Spring DTO @NotNull validation

Let us take a simple DTO to represent a HTTP request body used to create a person, where we expect name and age to be not null. We use _javax_’s @NotNull annotation to validate the request fields, which we have defined to not be nullable.

For the below request:




{"age": 20,"description": "person with no name"}

We expect a validation error on the name field, however it passes the validators specified on the DTO.

Why?

The javax validator requires an instance of the object before it can validate it. Since the field is declared as a non-nullable, jackson-module-kotlin is providing a default value for the field based on its type. In the case of name(String) it sets it to an empty string, or 0 in case of age(Int).

Possible Workarounds

  1. Based on your use case, factor in the possibility of the value being the default value in the validation. (ie) validate against possible defaults.

This ensures that the name field has at least one character and fails validation on empty strings. Similarly for age it can be specified to have at least a value of 1.

2. Enabling the DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES for jackson-module-kotlin could help by throwing errors while constructing the object during deserialisation. These are different from validation errors and have to handled accordingly.

IMHO the former approach is preferable because apart from the fact it still throws a validation error, it allows you to specify more expressive conditions for validation making it more readable.

Spring does not have support for Coroutines

Coroutines were made stable in the release of Kotlin version 1.3. However they are still not supported by Spring out of the box.

Why?

Spring framework’s dispatchers do no support constructs generated by the Kotlin compiler for Coroutines. Kotlin compiler generates a **Continuation** parameter for **suspended** functions, for which Spring has no built-in handlers.

Possible solutions

Thanks to the efforts of Konrad, Coroutines can be used in Spring by using the spring-kotlin-coroutine. The library provides modules to support Coroutines for different applications/domains within Spring.

Or just leverage the @Async executors that come out of the box with Spring.

Spring is working on having more native support for Coroutines. Its status is tracked here. https://jira.spring.io/browse/SPR-15413

Further Reading


Hope you enjoyed reading this as much as I enjoyed writing it. If you think this will be of help to someone? Do not hesitate to share. If you liked it, tap the clap below so other people will see this here on Medium. Don’t forget to show some love by following the blog!