Ktor 3.0.0-beta-2 Help

Create, open and run a new Ktor project

In this tutorial, you will learn how to create, open and run your first Ktor server project. Once you get up and running, you can attempt a series of tasks to familiarize yourself with Ktor.

This is the first of a series of tutorials to get you started with building server applications with Ktor. You can do each tutorial independently, however, we strongly recommend that you follow the suggested order:

  1. Create, open and run a new Ktor project.

  2. Handle requests and generate responses.

  3. Create a RESTful API that generates JSON.

  4. Create a website using Thymeleaf templates.

  5. Create a WebSocket application.

  6. Integrate a database with Exposed.

Create a new Ktor project

One of the fastest ways to create a new Ktor project is by using the web-based Ktor project generator.

Alternatively, if you have intelliJ IDEA Ultimate installed, you can use the dedicated Ktor plugin to create a new project.

Use the Ktor project generator

To create a new project with the Ktor project generator, follow the steps below:

  1. Navigate to the Ktor Project Generator.

  2. In the Project artifact field, enter com.example.ktor-sample-app as the name of your project artifact.

    Ktor Project Generator with Project Artifact Name org.example.ktor-sample-app

  3. Click Configure to open the settings dropdown menu:

    expanded view of Ktor project settings

    The following settings are available:

    • Build System: Choose the desired build system. This can be Gradle with Kotlin or Groovy DSL, or Maven.

    • Ktor version: Choose the required Ktor version.

    • Engine: Select an engine used to run a server.

    • Configuration: Choose whether to specify server parameters in a YAML or HOCON file, or in code.

    • Include samples: Leave this option enabled to add sample code for plugins.

    For this tutorial you can leave the default values for these settings.

  4. Click Done to save the configuration and close the menu.

  5. Below you will find a set of plugins that you can add to your project. Plugins are building blocks that provide common functionality in a Ktor application, such as authentication, serialization and content encoding, compression, cookie support, and more.

    For the sake of this tutorial, no plugins need to be added to the project at this stage.

  6. Click the Download button to generate and download your Ktor project.

    Ktor Project Generator download button

Your download should start automatically.

Now that you have generated a new project, continue to unpack and run your Ktor project.

Use the Ktor plugin for intelliJ IDEA Ultimate

This section describes project setup using the Ktor plugin for Intellij IDEA Ultimate.

To create a new Ktor project, open IntelliJ IDEA, and follow the steps below:

  1. On the Welcome screen, click New Project.

    Otherwise, from the main menu, select File | New | Project.

  2. In the New Project wizard, choose Ktor from the list on the left.

  3. On the right pane, you can specify the following settings:

    Ktor Project Settings
    • Name: Specify a project name. Enter ktor-sample-app as the name of your project.

    • Location: Specify a directory for your project.

    • Website: Specify a domain used to generate a package name.

    • Artifact: This field shows a generated artifact name.

    • Engine: Select an engine used to run a server.

    • Include samples: Leave this option enabled to add sample code for plugins.

  4. Click Advanced Settings to expand the additional settings menu:

    Ktor Project Advanced Settings

    The following settings are available:

    • Build System: Choose the desired build system. This can be Gradle with Kotlin or Groovy DSL, or Maven.

    • Ktor version: Choose the required Ktor version.

    • Configuration: Choose whether to specify server parameters in a YAML or HOCON file, or in code.

    For the sake of this tutorial, you can leave the default values of these settings.

  5. Click Next to go to the next page.

    Ktor plugins

    On this page, you can choose a set of plugins - building blocks that provide common functionality of a Ktor application, for example, authentication, serialization and content encoding, compression, cookie support, and so on.

    For the sake of this tutorial, no plugins need to be added to the project at this stage.

  6. Click Create and wait until IntelliJ IDEA generates a project and installs the dependencies.

Now that you've created a new project, continue to learn how to open, explore and run the application.

Unpack and run your Ktor project

In this section you will learn how to unpack, build and run the project from the command line. The descriptions below assume that:

  • You have created and downloaded a project called ktor-sample-app.

  • This has been placed in a folder called myprojects in your home directory.

If necessary, alter the names and paths to match your own setup.

Open a command line tool of your choice and follow the steps:

  1. In a terminal, navigate to the folder where you downloaded the project:

    cd ~/myprojects
  2. Unpack the ZIP archive into a folder of the same name:

    unzip ktor-sample-app.zip -d ktor-sample-app
    tar -xf ktor-sample-app.zip

    Your directory will now contain the ZIP archive and the unpacked folder.

  3. From the directory, navigate into the newly created folder:

    cd ktor-sample-app
  4. On macOS/UNIX systems, you will need to make the gradlew Gradle helper script executable. To do that, use the chmod command:

    chmod +x ./gradlew
  5. To build the project, use the following command:

    ./gradlew build
    gradlew build

    If you see that your build has been successful you can execute the project, again via Gradle.

  6. To run the project, use the following command:

    ./gradlew run
    gradlew run
  7. To verify the project is running, open a browser at the URL mentioned in the output (http://0.0.0.0:8080). You should see the message "Hello World!" displayed on the screen:

    Output of generated ktor project

Congratulations! You have successfully started your Ktor project.

Note that the command line is unresponsive because the underlying process is busy running the Ktor application. You can press CTRL+C to terminate the application.

Open, explore and run your Ktor project in IntelliJ IDEA

Open the project

If you have IntelliJ IDEA installed, you can easily open the project from the command line.

Make sure you are in the project folder and then type the idea command, followed by a period to represent the current folder:

idea .

Alternatively, to open the project manually launch IntelliJ IDEA.

If the Welcome screen opens, click Open. Otherwise, go to File | Open in the main menu and select the ktor-sample-app folder to open it.

Explore the project

Whichever option you choose, the project should open as shown below:

Generated Ktor project view in IDE

In order to explain the project layout we have expanded the structure in the Project view and selected the file settings-gradle.kts.

You will see that the code to run your application lives in packages under src/main/kotlin. The default package is called com.example and contains a subpackage called plugins. Two files have been created within these packages, named Application.kt and Routing.kt

Ktor project src folder structure

The name of the project is configured in settings-gradle.kts.

Contents of settings.gradle.kt

Configuration files, and other kinds of content, live within the src/main/resources folder.

Ktor project resources folder structure

A skeleton test has been created in a package under src/test/kotlin.

Ktor project test folder structure

Run the project

To run the project from within IntelliJ IDEA:

  1. Open the Gradle tool window by clicking the Gradle icon (intelliJ IDEA gradle icon) on the right sidebar.

    Gradle tab in IntelliJ IDEA
  2. Within this tool window navigate to Tasks | application and double-click on the run task.

    Gradle tab in IntelliJ IDEA
  3. Your Ktor application will start in the Run tool window at the bottom of the IDE:

    Project running in terminal

    The same messages that were previously displayed on the command line will now be visible in the Run tool window.

  4. To confirm the project is running, open your browser at the specified URL (http://0.0.0.0:8080).

    You should once again see the message "Hello World!" displayed on the screen:

    Hello World in Browser Screen

You can manage the application via the Run tool window.

  • To terminate the application, click the stop button intelliJ IDEA terminate icon

  • To restart the process, click the rerun button intelliJ IDEA rerun icon

These options are explained further in the IntelliJ IDEA Run Tool Window documentation.

Additional Tasks To Attempt

Here are some additional tasks you may wish to try:

  1. Change the default port.

  2. Change the port via YAML.

  3. Add a new HTTP endpoint.

  4. Configure static content.

  5. Write an integration test.

  6. Register error handlers.

These tasks do not depend on one another, but gradually increase in complexity. Attempting them in the order declared is the easiest way to learn incrementally. For simplicity, and to avoid duplication, the descriptions below assume you are attempting the tasks in order.

Where coding is required we have specified both the code and the corresponding imports. The IDE may add these imports for you automatically.

Change the default port

In the Project view navigate to the src/main/kotlin folder and then into the single package that has been created for you and follow the steps:

  1. Open the Application.kt file. You should find code similar to the following:

    fun main() { embeddedServer( Netty, port = 8080, // This is the port on which Ktor is listening host = "0.0.0.0", module = Application::module ).start(wait = true) } fun Application.module() { configureRouting() }
  2. In the embeddedServer() function, change the port parameter to another number of your choosing, such as "9292".

    fun main() { embeddedServer( Netty, port = 9292, host = "0.0.0.0", module = Application::module ).start(wait = true) }
  3. Click on the rerun button (intelliJ IDEA rerun button icon) to restart the application.

  4. To verify that your application is running under the new port number, you can open your browser at the new URL (http://0.0.0.0:9292), or create a new HTTP Request file in IntelliJ IDEA:

    Testing port change with an HTTP request file in IntelliJ IDEA

Change the port via YAML

When creating a new Ktor project, you have the option to store configuration externally, within either a YAML or a HOCON file:

Ktor project generator configuration options

If you had chosen to store configuration externally then this would be the code in Application.kt:

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) @Suppress("unused") fun Application.module() { configureRouting() }

These would be the values stored in the configuration file within src/main/resources/:

ktor: application: modules: - com.example.ApplicationKt.module deployment: port: 8080
ktor { deployment { port = 8080 port = ${?PORT} } application { modules = [ com.example.ApplicationKt.module ] } }

In this case you do not need to alter any code to change the port number. Simply alter the value in the YAML or HOCON file and restart the application. The change can be verified in the same way as with the default port above.

Add a new HTTP endpoint

Next, you will create a new HTTP endpoint that will respond to a GET request.

In the Project tool window, navigate to the src/main/kotlin/com/example folder and follow the steps:

  1. Open the Application.kt file and find the configureRouting() function.

  2. In intelliJ IDEA, navigate to the configureRouting() function by placing the caret over the function name and pressing ⌘Cmd+B.

    Alternatively, you can navigate to the function by opening the Routing.kt file.

    This is the code you should see:

    fun Application.configureRouting() { routing { get("/") { call.respondText("Hello World!") } } }
  3. To create a new endpoint, insert the additional five lines of code shown below:

    fun Application.configureRouting() { routing { get("/") { call.respondText("Hello World!") } get("/test1") { val text = "<h1>Hello From Ktor</h1>" val type = ContentType.parse("text/html") call.respondText(text, type) } } }

    Note that you can change the /test1 URL to be whatever you like.

  4. In order to make use of ContentType, add the following import:

    import io.ktor.http.*
  5. Click on the rerun button (intelliJ IDEA rerun button icon) to restart the application.

  6. Request the new URL in the browser (http://0.0.0.0:9292/test1). The port number you should use will depend on whether you have attempted the first task (Changing the default port). You should see the output displayed below:

    A browser screen displaying Hello from Ktor

    If you have created an HTTP Request File you can also verify the new endpoint there:

    An HTTP request file in intelliJ IDEA

    Note that a line containing three hashes (###) is needed to separate different requests.

Configure static content

In the Project tool window, navigate to the src/main/kotlin/com/example/plugins folder and follow the steps:

  1. Open the Routing.kt file.

    Once again this should be the default content:

    fun Application.configureRouting() { routing { get("/") { call.respondText("Hello World!") } }

    For this task it does not matter whether you have inserted the content for the extra endpoint specified in Adding a new HTTP endpoint.

  2. Add the following line to the routing section:

    fun Application.configureRouting() { routing { // Add the line below staticResources("/content", "mycontent") get("/") { call.respondText("Hello World!") } }

    The meaning of this line is as follows:

    • Invoking staticResources() tells Ktor that we want our application to be able to provide standard website content, such as HTML and JavaScript files. Although this content may be executed within the browser, it is considered static from the server's point of view.

    • The URL /content specifies the path that should be used to fetch this content.

    • The path mycontent is the name of the folder within which the static content will live. Ktor will look for this folder within the resources directory.

  3. Add the following import:

    import io.ktor.server.http.content.*
  4. In the Project tool window, right-click the src/main/resources folder and select New | Directory.

    Alternatively, select the src/main/resources folder, press ⌘Сmd+N, and click Directory.

  5. Name the new directory mycontent and press ↩Enter.

  6. Right-click on the newly created folder and click New | File.

  7. Name the new file "sample.html" and press ↩Enter.

  8. Populate the newly created file page with valid HTML, for example:

    <html lang="en"> <head> <meta charset="UTF-8" /> <title>My sample</title> </head> <body> <h1>This page is built with:</h1> <ol> <li>Ktor</li> <li>Kotlin</li> <li>HTML</li> </ol> </body> </html>
  9. Click on the rerun button (intelliJ IDEA rerun button icon) to restart the application.

  10. When you open your browser at http://0.0.0.0:9292/content/sample.html the content of your sample page should be displayed:

    Output of a static page in browser

Write an integration test

Ktor provides support for creating integration tests, and your generated project comes bundled with this functionality.

To make use of this, follow the steps below:

  1. Create a new directory under src called "test" and a subdirectory called "kotlin".

  2. Create a new package inside src/test/kotlin called "com.example".

  3. Within src/test/kotlin/com.example create a new file called "ApplicationTest.kt".

  4. Open the ApplicationTest.kt file and add the code below:

    class ApplicationTest { @Test fun testRoot() = testApplication { application { module() } val response = client.get("/") assertEquals(HttpStatusCode.OK, response.status) assertEquals("Hello World!", response.bodyAsText()) } }

    The testApplication() method creates a new instance of Ktor. This instance is running inside a test environment, as opposed to a server such as Netty.

    You can then use the application() method to invoke the same setup that is called from embeddedServer().

    Finally, you can use the built-in client object and JUnit assertions to send a sample request and check the response.

  5. Add the following required imports:

    import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.testing.* import org.junit.Assert.assertEquals import org.junit.Test

The test can be run in any of the standard ways for executing tests in IntelliJ IDEA. Note that, because you are running a new instance of Ktor, the success or failure of the test does not depend on whether your application is running at 0.0.0.0.

If you have successfully completed adding a new HTTP endpoint, you should be able to add this additional test:

@Test fun testNewEndpoint() = testApplication { application { module() } val response = client.get("/test1") assertEquals(HttpStatusCode.OK, response.status) assertEquals("html", response.contentType()?.contentSubtype) assertContains(response.bodyAsText(), "Hello From Ktor") }

The following additional import is required:

import kotlin.test.assertContains

Register error handlers

You can handle errors in your Ktor application by using the StatusPages plugin.

This plugin is not included in your project by default. You could have added it to your project via the Plugins section in the Ktor Project Generator, or the Project Wizard in IntelliJ IDEA. Since you've already created your project, in the next steps you will learn how to add and configure the plugin manually.

There are four steps to achieving this:

  1. Add a new dependency in the Gradle build file.

  2. Install the plugin and specify an exception handler.

  3. Write sample code to trigger the handler.

  4. Restart and invoke the sample code.

Add a new dependency

In the Project tool window, navigate to the src/test/kotlin folder and follow the steps:

  1. Open the build.gradle.kts file.

  2. In the dependencies section add the extra dependency as shown below:

    dependencies { // The new dependency to be added implementation("io.ktor:ktor-server-status-pages:$ktor_version") // The existing dependencies implementation("io.ktor:ktor-server-core-jvm:$ktor_version") implementation("io.ktor:ktor-server-netty-jvm:$ktor_version") implementation("ch.qos.logback:logback-classic:$logback_version") testImplementation("io.ktor:ktor-server-test-host-jvm:$ktor_version") testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") }

    When you have done this you will need to reload the project to pick up this new dependency.

  3. Reload the project by pressing Shift+⌘Cmd+I on macOS or Ctrl+Shift+O on Windows.

Install the plugin and specify an exception handler

  1. Navigate to the configureRouting() method in Routing.kt and add the following lines of code:

    fun Application.configureRouting() { install(StatusPages) { exception<IllegalStateException> { call, cause -> call.respondText("App in illegal state as ${cause.message}") } } routing { get("/") { call.respondText("Hello World!") } } }

    These lines install the StatusPages plugin and specify what actions to take when an exception of type IllegalStateException is thrown.

  2. Add the following import:

    import io.ktor.server.plugins.statuspages.*

Note that an HTTP error code would usually be set in the response, but for the purpose of this task, the output is displayed directly in the browser.

Write sample code to trigger the handler

  • Staying within the configureRouting() method, add the additional lines as shown below:

    fun Application.configureRouting() { install(StatusPages) { exception<IllegalStateException> { call, cause -> call.respondText("App in illegal state as ${cause.message}") } } routing { get("/") { call.respondText("Hello World!") } get("/error-test") { throw IllegalStateException("Too Busy") } } }

    You have now added an endpoint with the URL /error-test. When this endpoint is triggered, an exception will be thrown with the type used in the handler.

Restart and invoke the sample code

  1. Click on the rerun button (intelliJ IDEA rerun button icon) to restart the application.

  2. In your browser, navigate to the URL http://0.0.0.0:9292/error-test. You should see the error message displayed as shown below:

    A browser screen with message `App in illegal state as Too Busy`

Next steps

If you've made it to the end of the additional tasks, you now have a grasp of configuring the Ktor server, integrating a Ktor plugin, and implementing a new route. However, this is just the beginning. To delve deeper into the foundational concepts of Ktor, continue to the next tutorial in this guide.

Next up, you will learn how to handle requests and generate responses by creating a Task Manager application.

Last modified: 09 August 2024