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 :
- Spring requires classes with annotations to be open, all classes in Kotlin are closed by default. This can be resolved by adding the
kotlin-springplugin to the gradle config.
- Hibernate entities require a no-arg constructor, Kotlin has provided a compiler plugin
kotlin-jpato 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
age to be not null. We use
@NotNull annotation to validate the request fields, which we have defined to not be nullable.
For the below request:
"description": "person with no name"
We expect a validation error on the
name field, however it passes the validators specified on the DTO.
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
- 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
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.
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.
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
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!