Reactive Kotlin - building reactive REST service in Kotlin
When developing an application on java stack that exposes REST API you have quite a lot of options and for majority of problems using Spring is a pretty good solution. Why would you want to consider a reactive approach then?
No more thread per request
Traditional web based applications (based on e.g. tomcat) use thread per request approach. The requests are blocking and synchronous especially when used with blocking I/O (JDBC, JPA) - such threads are not freed until the I/O wait is over. To scale such solutions you need to add servers that add more thread pools. Reactive (non-blocking) approach uses so called event loop. This means that thread does not wait for time consuming operation to finish. It creates a subscription for when operation is finished and in the meantime it (same thread) can pick up e.g. next request. When response is ready, event with response is fired back to subscription and any other thread can pick it up and further process the response. This scales better - does not require more threads over bigger load - just more CPU power.
Replace threads with coroutines
Kotlin has an interesting mechanism of coroutines. They are lightweight “threads” allowing to write non-blocking code in an imperative way. Of course they are not really threads and internally they use mechanism of continuations - this means that thread can stop executing a coroutine, do some other work and then later get back and resume it (or any other thread can resume). They are supported at language level by Kotlin. They are very fast and cheap in creation, there is no additional overhead of switching context between them. It’s a perfect tool for the reactive programming.
Write less code
Reactive appraoch lets you write less code: you’ll replace control statements like ‘if’ or ‘for’ with their imperative counterparts and in many places you’ll be able to use functional programming. Write in Kotlin and your code will become even more compact.
Spring, Kotlin and coroutines
Spring has a lot to offer when it comes to reactive programming. If your service uses database, then Spring Data Reactive Repositories provide access to: Mongo, Cassandra, Redis, Couchbase and via Spring Data R2DBC you can access SQL Server, PostgreSQL, MySQL, MariaDB and H2. Calling external APIs can be done via Spring’s reactive WebClient and Spring Cloud Streams will let you access services like RabbitMQ, RocketMQ, Kafka, Kinesis or Azure Event Hubs.
Spring also widely supports Kotlin’s coroutines.
Lets see some examples.
Quarkus is a very interesting option and in almost no-time it became serious alternative to Spring. Since beginning Quarkus was ment to be lightning fast which is achieved mostly by using GraalVM to build native binaries. Its ecosystem is hudge and growing fast and if you are missing anything - you can just write your own Quarkus extension and publish it in Quarkiverse Hub. By The way, their community is very helpful.
When it comes to reactive programming they utilise Munity library. In reactive manner out of the box you will have access to DB2, MySQL, PostgreSQL, Redis and Mongo. They also work on Reactive Hibernate extension which may be quite an interesting option (working on top of reactive clients for DB2, MySQL and PostgreSQL). When it comes to messaging there are extensions for Kafka, MQTT and AMQP.
In Quarkus Kotlin is just an addition (it operates in JVM world) and there is no specific timeline for supporting coroutines yet.
Still there is nothing against using it with Quarkus and below is a sample application.
Ktor just has to be in this blog post. It’s written in Kotlin, with Kotlin in mind and it’s JetBrains that stand behind (and it uses coroutines widely across whole implementation). It’s ideal for microservices but if you come from java/spring world then you’ll have to give yourself some time to master this library. It covers many to all aspects of writing web application but it won’t help you with anything else, so things like data access are on you.
In Ktor, application can be very minimalistic:
Is it worth it
Personally I think that data access may be the biggest problem of adapting reactive programming in any project - especially when you don’t imagine data access layer without JPA. Reactive Hibernate from Qarkus sounds promissing but I do not think it is production ready - I’ll definitely give it a try in nearest future. Otherwise it’s definitely worth it - for me thoe most appealing advantage is better scalability and use of resources which makes such applications cloud ready and in the end should cost us less even when run under heavy load.
Source code for mentioned reactive applications are on our official Github repo.