Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Using Kotlin With Ktor to Create Web Apps

DZone's Guide to

Using Kotlin With Ktor to Create Web Apps

Follow along as we make a simple application to demonstrate how Kotlin and this great library can be used to create web apps.

· Web Dev Zone ·
Free Resource

Jumpstart your Angular applications with Indigo.Design, a unified platform for visual design, UX prototyping, code generation, and app development.

This article is featured in the new DZone Guide to Web Development. Get your free copy for more insightful articles, industry statistics, and more!

When Google made Kotlin an official language for Android a few months ago at Google I/O, the language quickly gained a lot of popularity in the Android world. On the server side though, Kotlin is not as broadly adopted, and some people still seem to be cautious when backend services are involved. Other developers are convinced that Kotlin is mature enough and can safely be used for any server application in which Java could play a role otherwise.

If you want to develop web apps with Kotlin, you can choose from various web frameworks like Spring MVC/WebFlux, Vert.x, Vaadin, and basically everything available for the JVM. Besides the aforementioned frameworks, there’s also a Kotlin specific library available for creating web applications, called ktor. After reading this article, you’ll know what ktor is, its advantages are, and how you can quickly develop a web application in Kotlin.

Ktor

The web application framework ktor, written in Kotlin, is meant to provide a tool for quickly creating web applications with Kotlin. The resulting software may be hosted in common servlet containers, like Tomcat, or standalone in a Netty, for example. Whatever kind of hosting you choose, ktor is making heavy use of Kotlin coroutines, so that it’s implemented 100% asynchronously and mainly non-blocking. Ktor does not dictate which frameworks or tools you use, so you can choose whatever logging, DI, or templating engine you like. The library is pretty light-weight in general but is still very extensible through a plugin mechanism.

One of the greatest advantages attributed to Kotlin is its ability to provide type-safe builders, also known as Domain Specific Languages (DSL). Many libraries already provide DSLs as an alternative to common APIs, such as the Android library Anko, the Kotlin html builder, or the freshly released Spring 5 framework. As we will see in the upcoming examples, ktor also makes use of such DSLs, which enable the user to define the web app’s endpoints in a very declarative way.

Example Application

In the following example, a small RESTful web service will be developed with ktor. The service will use an in-memory repository with simple Person resources, which it exposes through a JSON API. Let’s look at the components.

Person Resource and Repository

According to the app’s requirements, a resource, “Person,” is defined as a data class, and the corresponding repository is defined as an object, Kotlin’s way of applying the Singleton pattern to a class.

data class Person(val name: String, val age: Int){
    var id: Int? = null
}

The resource has two simple properties which need to be defined when a new object is constructed, whereas the id property is set later when stored in the repository.

The Person repository is rather unspectacular and not worth observing. It uses an internal data store and provides common CRUD operations.

Endpoints

The most important part of the web application is the configuration of its endpoints, exposed as a REST API. The following endpoints will be implemented: The application won’t support an update operator via PUT.

Image title

Routing With Ktor

Now ktor comes into play with its structured DSL, which will be used for defining the previously  shown endpoints, a process often referred to as “routing.” Let’s see how it works:

fun Application.main() {
   install(DefaultHeaders)
   install(CORS) {
maxAge = Duration.ofDays(1)
   }
   install(ContentNegotiation){
     register(ContentType.Application.Json,
     GsonConverter())
   }

   routing {
     get(“/persons”) {
     LOG.debug(“Get all Person entities”)
     call.respond(PersonRepo.getAll())
   }
 // more routings
}

The fundamental class in the ktor library is Application, which represents a configured and, eventually, running webservice instance. In the snippet, an extension function main() is defined on Application, in which it’s possible to call functions defined in Application directly, without additional qualifiers. This is done by invoking install()multiple times, a function for adding certain ApplicationFeatures into the request processing pipeline of the application. These features are optional and the user can choose from various types. The only interesting feature in the shown example is ContentNegotiation, which is used for the (de-)serialization of Kotlin objects to and from JSON, respectively. The Gsonlibrary is used as a backing technology.

The routing itself is demonstrated by defining the GET endpoint for retrieving all Person resources here. It’s actually straight-forward since the result of the repository call getAll() is just delegated back to the client. The call.respond() invocation will eventually reach the Gson Support feature, taking care of transforming the Person into its JSON representation. The same happens for the remaining four REST endpoints, which will not be shown explicitly here.

The HTML Builder

Another cool feature of ktor is its integration with other Kotlin DSLs like the HTML builder, which can be found on GitHub. By adding a single additional dependency to a ktor app, this builder can be used with the extension function call.respondHtml(), which expects type-safe HTML code to be provided. In the following example, a simple greeting to the readers is included, which the web service exposes as its index page.

get("/”) {
 call.respondHtml {
   head {
     title(“ktor Example Application”)
   }
   body {
      h1 { +”Hello DZone Readers” }
     p {+”How are you doing?” }
   }
 }
}

Starting the Application

After having done the configuration of a ktor application, there’s still a need to start it through a regular main method. In the demo, a Netty server is started standalone by doing the following:

fun main(args: Array<String>) {
embeddedServer(Netty, 8080, module = Application::main).start(wait = true)
}

The starting is made pretty simple by just calling the embeddedServer() method with a Netty environment, a port, and the module to be started, which happens to be the thing defined in the Application.main() extension function from the previous example.

Testing

A web framework or library is only applicable if it comes with integrated testing means, which ktor actually does. Since the GET routing for retrieving all Person resources was already shown, let’s have a look at how the endpoint can be tested.

@Test
fun getAllPersonsTest() = withTestApplication(Application::main) {
  val person = savePerson(gson.toJson(Person(“Bert”, 40)))
  val person2 = savePerson(gson.toJson(Person(“Alice”, 25)))
  handleRequest(HttpMethod.Get, “/persons”) {
     addHeader(“Accept”, json)
  }.response.let {
       assertEquals(HttpStatusCode.OK,it.status())
       val response = gson.fromJson(it.content,Array<Person>::class.java)
       response.forEach { println(it) }
       response.find { it.name == person.name } ?: fail()
       response.find { it.name == person2.name } ?: fail()
   }
   assertEquals(2, PersonRepo.getAll().size)
 }

This one is quite simple: Two resource objects are added to the repository, then the GET request is executed and some assertions are done against the web service response. The important part is with TestApplication(), which ktor offers through its testing module and makes it possible to directly test the Application.

The article presented basically everything worth knowing in order to get started with ktor web applications. Formore details, I recommend the ktor homepage or the samples included in the ktor repository.

The complete source code of the developed web application can be found on GitHub, it’s backed by a Gradle build.

Take a look at an Indigo.Design sample application to learn more about how apps are created with design to code software.

Topics:
web dev ,kotlin ,ktor ,web application development

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}