Step by step guide to building Web API with Kotlin and Dropwizard
Tags: web, kotlin
Published: 2017-09-16 22:25:40

---
title: "Step by step guide to building Web API with Kotlin and Dropwizard"
published: true
description: "Step by step guide to building Web API with Kotlin and Dropwizard"
tags: web, kotlin
---

In this post we'll set a foundation for Web API server written in Kotlin and then build upon it in future posts covering topics like database access, authentication and deployment.

# Why Kotlin?

[Kotlin](https://kotlinlang.org/) is a great language for JVM that generated much buzz when it was declared to be one of the officially supported languages for Android development.

However, the main strength of Kotlin is its amazing Java interoperability story and that makes it a great choice for building backend services as well.

We could of course use one of the newest cool frameworks for Kotlin, like [KTOR](http://ktor.io/), but why do that when we can leverage that interoperability story to use an amazing existing Java ecosystem that has been polished for God knows how long already?

# Dropwizard

One of the projects that tries to consolidate some of the better practices of web development on JVM is [Dropwizard](http://www.dropwizard.io/).

It includes:
- Jetty for HTTP
- Jersey for REST
- Jackson for JSON
- Logback and slf4j for logging
- JDBI and Hibernate for database access
- etc

Dropwizard itself has pretty awesome docs including [getting started guide](http://www.dropwizard.io/1.1.4/docs/getting-started.html), but it's all Java and Maven, which kind of makes you feel like writing legacy code from the get go.

How about living a little and making it all Kotlin and [Gradle](https://gradle.org/)?

# New Kotlin application

We'll build a simplistic Calculator web service. The full source code is available on [GitHub](https://github.com/groz/kotlin-webapi).

Easiest way to get started is to create a Gradle project in [IntelliJ](https://www.jetbrains.com/idea/download) choosing a Kotlin (JVM) template.

Set `GroupID: to.dev.example`, `ArtifactID: kotlin-webapi`, check `Use auto-import` and you are good to go. IntelliJ will setup basic project layout for compiling Kotlin code.

Add a `src/main/kotlin/to/dev/example/MainApp.kt` file, it will contain our application's entry point:

```kotlin
package to.dev.example

fun main(args: Array<String>) {
    println("Hello, Kotlin!")
}
```

By default IntelliJ creates a Gradle build for a library, not an application. Let's add some lines to the `build.gradle` file at the root of our project to turn it into an runnable application:

```groovy
apply plugin: 'application'
mainClassName = 'to.dev.example.MainAppKt'
```

Notice the `MainAppKt` class name? Where does it come from?

There are no functions outside of classes in Java world, so Kotlin  conveniently created a class for us behind the scenes, named it `<FileName>Kt` and put the `main` function in there.

Now we can go to the project root and type: `$ ./gradlew run` to make Gradle build and run our modest application.

```bash
:compileKotlin UP-TO-DATE
:compileJava NO-SOURCE
:copyMainKotlinClasses UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:run
Hello, Kotlin!
```

Now that we have a running application, let's add some Dropwizard to it.

# Dropwizard application

Dropwizard is structured as a collection of smaller libraries, so that you can add only the ones you need.
For now `dropwizard-core` will be enough.

Add the following lines to the same `build.gradle` file:

```groovy
ext.dropwizard_version = '1.1.4'

dependencies {
    compile "io.dropwizard:dropwizard-core:$dropwizard_version"
}
```

## Configuration

Dropwizard has a notion of configuration files built into it so deep that in fact the first thing you need to do to have a running Dropwizard application is to define the configuration class derived from `io.dropwizard.Configuration`.

This configuration will primarily be used to distinguish between development and production settings like database connection strings.

Kotlin makes it very easy to create such simple classes. Just one line of code:

```kotlin
class CalculatorConfig(val name: String = "unknown") : Configuration()
```

Of course we need an actual configuration file to be parsed into this config. 
Add a `config/local.yaml` class to the root of our project:

```yaml
name: Kotlin Calculator
```

## Application

To create a web service we will need to register components with Jersey.
Components can easily be enhanced with standard and self-explanatory `javax.ws.rs` annotations:

```kotlin
@Path("/")
class CalculatorComponent {
    @Path("/add")
    @GET
    fun add(@QueryParam("a") a: Double, @QueryParam("b") b: Double): Double {
        return a + b
    }

    @Path("/multiply")
    @GET
    fun multiply(@QueryParam("a") a: Double, @QueryParam("b") b: Double): Double {
        return a * b
    }

    @Path("/divide")
    @GET
    fun divide(@QueryParam("a") a: Double, @QueryParam("b") b: Double): Double {
        if (b == .0) {
            throw WebApplicationException("Can't divide by zero")
        }
        return a / b
    }
}
```

Combined with your configuration declared above a class derived from `io.dropwizard.Application` forms a core of your Dropwizard application and that's where we will register our component with Jersey:

```kotlin
class CalculatorApp : Application<CalculatorConfig>() {
    override fun run(configuration: CalculatorConfig, environment: Environment) {
        println("Running ${configuration.name}!")
        val calculatorComponent = CalculatorComponent()
        environment.jersey().register(calculatorComponent)
    }
}
```

Note: this registers a singleton component which will be shared between requests. There are other much more powerful ways to control creation of components for serving resources, but that's a topic for another day.

Now to create an object of this class and pass it command line arguments from our `main` function:

```kotlin
fun main(args: Array<String>) {
    CalculatorApp().run(*args) // use collection as a varargs
}
```

# Run 

```bash
$ ./gradlew run
...
:run
usage: java -jar project.jar [-h] [-v] {server,check} ...

positional arguments:
  {server,check}         available commands

optional arguments:
  -h, --help             show this help message and exit
  -v, --version          show the application version and exit
```

Looks like we need to pass some command line arguments to the app. 
We should build an artifact and run it as a standalone Java application, but I prefer to hack it for now providing those arguments to the run task in `build.gradle` file:

```groovy
run {
    args = ['server', 'config/local.yaml']
}
```

Run again:

```bash
$ ./gradlew run
...
Running Kotlin Calculator!
...
INFO  [2017-09-16 21:17:27,181] io.dropwizard.server.ServerFactory: Starting CalculatorApp
...
INFO  [2017-09-16 21:17:27,664] io.dropwizard.jersey.DropwizardResourceConfig: The following paths were found for the configured resources:

    GET     / (to.dev.example.CalculatorComponent)
    GET     /add (to.dev.example.CalculatorComponent)
    GET     /multiply (to.dev.example.CalculatorComponent)

...

INFO  [2017-09-16 21:17:27,681] org.eclipse.jetty.server.AbstractConnector: Started application@720bf653{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
INFO  [2017-09-16 21:17:27,682] org.eclipse.jetty.server.AbstractConnector: Started admin@360bc645{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
...
```

As you can see in the above logs web app started listening on default port `8080` and admin port `8081`:

```bash
$ curl "localhost:8080/add?a=5&b=10"
15
$ curl "localhost:8080/multiply?a=5&b=10"
50
$ curl "localhost:8080/divide?a=5&b=0"
{"code":500,"message":"Can't divide by zero"}
```

VoilÃ , we have a self-contained web service written in less than 50 lines of Kotlin code capable of serving 30,000-50,000 requests per second.

In the next posts we'll cover testing, serving JSON objects, creating a standalone app for deployment, database access and authentication.