Building a Kotlin Dropwizard Maven REST API from scratch: Part 2

Part 2: Add Dropwizard

After creating our POM file in Part 1, we are ready to start writing some Dropwizard Kotlin code! We first need to create our folder structure. Next to your pom.xml file; create a folder named src, then inside there create one named main, and finally in there ,create two folders, kotlin and resources.

Inside the Kotlin folder, we need to create our package structure. Unlike Java, this is actually not required but if you want to be consistent you can. So for this example, you will want to create in kotlin three nested folders, com -> mannanlive -> dropwizardkotlinapp (if you change these, make sure you change any references in the subsequent examples). Finally, in the dropwizardkotlinapp you will want to create two folders, configuration and resources (Dropwizard version of controllers). It should look something like the below.

|- pom.xml
|- src
|- main
|- resources
|- kotlin
|- com
|- mannanlive
|- kotlindropwizardapp
|- configuration
|- resources

Now similar to Spring’s application.properties, Dropwizard supports a similar external configuration approach. It is a little more flexible in the approach, for this example, create a file call app-config.yml inside the src/main/resources folder. In it we define a single example property.

testProp: abc

But how do we reference this property in our code. We need to define our application configuration class that is dynamically bound at runtime to our newly created configuration file. In our kotlindropwizardapp/configuration folder, create a new file AppConfig.kt. Inside we will create a class that extends the Dropwizard Configuration class, that will know to look for our newly created test property.

package com.mannanlive.dropwizardkotlinapp.configuration

import com.fasterxml.jackson.annotation.JsonProperty
import io.dropwizard.Configuration

class AppConfig(@JsonProperty("testProp") val testProp: String) : Configuration()

However this configuration file does not do much on it’s own. To launch an instance of our Dropwizard RESTful server, we need our own implementation of the Application class. In the the kotlindropwizardapp folder, create App.kt and implement the abstract class. We will need a static main method to launch the application from the command line, this needs to match the mainClass property in the Shade plugin of the POM file we created in Step 1. The second part is that it must use the configuration class we created above. It should look something like the below, note the use of the Kotlin spread operator to pass the arguments to the application. We will cover what arguments need to be passed in the next section.

package com.mannanlive.dropwizardkotlinapp

import com.mannanlive.dropwizardkotlinapp.configuartion.AppConfig
import io.dropwizard.Application
import io.dropwizard.setup.Environment

class App : Application<AppConfig>() {
    companion object {
        @JvmStatic fun main(args : Array<String>) = App().run(*args)
    }

    override fun run(config: AppConfig, env: Environment) { }
}

Congratulations, you have built a Dropwizard application! Unfortunately it doesn’t do much. To add endpoints we need to add Resources (a.k.a. controllers in the Spring frameworks) so in our kotlindropwizardapp/resources folder, lets create one by creating a file named EchoResource.kt (feel free to change this to whatever makes sense for your application). You can use the below as an example as it demonstrates a few different types that you can use. It also uses Kotlin’s anonymous objects so we don’t have to worry about creating an object to be mapped to JSON (commonly referred to as a data transfer object – DTO).

package com.mannanlive.dropwizardkotlinapp.resources

import com.fasterxml.jackson.annotation.JsonFormat
import java.util.*
import javax.ws.rs.*
import javax.ws.rs.core.MediaType

@Path("/echo")
@Produces(MediaType.APPLICATION_JSON)
class EchoResource(private val property: String) {

    @GET
    fun get(@QueryParam("query") @DefaultValue("default") queryParam: String) : Any = object {
        val query : String = queryParam
        val prop : String = property
        val number : Long = 123
        val bool : Boolean = false
        val array : List<Int> = listOf(456, 789)
        val map : Map<String, Double> = mapOf(Pair("rate", 11.5))
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
        val date : Date = Date(1548930042343)
    }
}

The last piece of this puzzle is to connect this EchoResource to our application. To do this, we need to add a line to our App.kt so it knows to use it, add the below line in the run method (don’t forget to import the package too).

import com.mannanlive.dropwizardkotlinapp.resources.EchoResource

override fun run(config: AppConfig, env: Environment) {
    env.jersey().register(EchoResource(config.testProp))
}

We are done with the production code, and you have built your first Dropwizard Kotlin Maven REST endpoint (what a mouthful). If you aren’t sure how to run it, don’t worry, we will cover that in the next part. We will also cover much more, including how to test it.

About the Author

Mannan

Mannan is a software engineering enthusiast and has been madly coding since 2002. When he isn't coding he loves to travel, so you will find both of these topics on this blog.

Leave a Reply

Your email address will not be published. Required fields are marked *