Deploy a microservice in Kotlin with Ktor — Part 3
Part 3. Access our database with Jetbrains Exposed
In the first two parts we created a Ktor project and designed our API. This third part is about storing data in a database.
Jetbrains provides an ORM framework for Kotlin called Exposed. Since we are fully committed to Kotlin and building a Ktor microservice, we didn’t really challenge using Exposed when we started. Nonetheless, despite its verbosity, Exposed has Coroutines support and, as expected, lives up to our expectations.
Connecting a database to our microservice required three layers :
- the database itself
- a connection (with a connection pool)
- an ORM to manipulate our data

PostgreSQL
Everything has to be built on top of a database. Since Exposed supports a lot of databases (H2, MySQL, SQLite, PostgreSQL, …), we chose PostgreSQL since we have experience with it.
Docker config
Setting up such a database is not really complex thanks to Docker. We wrote a docker-compose.yml
file to quickly set up a postgres database:
Add some configuration
Ktor allows us to access property values specified in application.conf
in code. We can add some configuration values to our application.conf
file that will be used in the next section. We defined some values to connect with the database.
HikariCP
Database connections are expensive operations. We need a database connection container which allows us to reuse a number of existing connections. This will save the cost of performing a huge number of expensive database trips.
HikariCP is a “zero-overhead” production ready JDBC connection pool. It is important to have a connection pool so we can scale up our project and increase our users efficiently. Let’s connect our connection pool with our database and initialize everything in the main Application.kt
file.
And don’t forget to call init
from Application.kt
Exposed
Jetbrains Exposed is an ORM framework for Kotlin. Exposed offers two levels of database access: typesafe SQL wrapping DSL and lightweight data access objects.

Exposed comes in two flavors: DSL (Domain Specific Language) and DAO (Data Access Object). On a high level, DSL means type-safe syntax that is similar to SQL whereas DAO means doing CRUD operations on entities.
Since we are code-generating our API, we thought it will be more interesting to use the DAO API of Exposed to be able to map
easily our database objects into API objects.
Manipulate the data
Creating a table in the DAO API of Exposed is represented by an object
An entity instance or a row in the table is defined as a class instance:
Since Exposed 0.15.1 there is a bridge function that gives us a safe way to interact with Exposed within suspend blocks: newSuspendedTransaction
And the magic occurs when routing:
All in all
Even if Exposed is quite verbose, we felt it fits perfectly with Ktor at the moment. Also, as Android developers 🤖, being able to work with Coroutines is an added bonus for us and helped us quickly gain technical knowledge.
Thanks to Julien Salvi and Olivier Buiron for helping the team gain knowledge on Jetbrains Exposed 💪