Bootstrapping With Amper
The Amper build tool offers perhaps the simplest way of bootstrapping a Ktor application.
In this section, we walk you through the process of using Amper to set up and run a basic ‘Hello World’ server, and we explain what the different elements of the application do.
You can use this ‘Hello World’ project as the starting point for your own Ktor applications, or you can use other project creation tools if you prefer.
Task 4.1
Setting Up
-
Create a new directory for the application. Copy into that directory the Amper script1 from one of the earlier Kotlin programming tasks (e.g., Task 1.5, ‘Using Amper’).
Make sure that your version of Amper is up to date, with
./amper update(Adjust this and subsequent commands as necessary if you are on a Windows system.)
-
Initialize the project by entering
./amper initWhen the list of options appears, use the arrow keys to move down until ‘Ktor server application’ is selected, then press Enter.
Amper will now create the project structure and configuration files needed by Ktor, as well as the source code for a “Hello World” server.
-
Examine the contents of the YAML file
module.yaml:product: jvm/app settings: ktor: enabled jvm: mainClass: org.jetbrains.amper.ktor.ApplicationKt dependencies: - $ktor.server.core - $ktor.server.netty - $ktor.server.configYaml - ch.qos.logback:logback-classic:1.5.18 test-dependencies: - $ktor.server.testHostThis file uses the
mainClasssetting to specify the application entry point. The source code file corresponding to this entry point isApplication.kt, in thesrcdirectory.Note: in a real project, you should change that package name
org.jetbrains.amper.ktorto something more appropriate, both here and in the source code files.Notice also how
module.yamlspecifies a number of dependencies:- The core library needed by Ktor server applications
- The Netty framework, which provides all the low-level networking functionality
- A library to support server configuration using YAML files
- A logging library
- A server testing library
Different options are available for some of these dependencies. For example, you don’t have to build your application on top of the Netty server framework; you could use Eclipse Jetty instead.
-
Now look in the
resourcesdirectory. This holds two files,application.yamlandlogback.xml. The first of these is a YAML file containing the run-time configuration for the application itself:ktor: application: modules: - org.jetbrains.amper.ktor.ApplicationKt.module deployment: port: 8080This particular configuration states that the server will listen on port 8080 once deployed. It also identifies a module in the Ktor application.
Ktor applications have a modular structure, in which different aspects of the implementation are handled by distinct modules. A Ktor module is simply an extension function that you plug in to the
Applicationclass that represents the whole application.These modules can be listed individually in the
modules:section of the YAML file; alternatively, you can just link to a single module from the YAML file and then have that function make calls to the various other modules that make up the application. The latter approach is used here.The other file,
logback.xml, configures how logging is done by the application. If want you to change the amount of logging that is done, or change the format of the logged messages, you can do so by editing this file. -
The last part of the project that we must examine is the
srcdirectory. This holds two source code files,Application.ktandRouting.kt.Application.ktcontains these functions:fun main(args: Array<String>) { io.ktor.server.netty.EngineMain.main(args) } fun Application.module() { configureRouting() }The first is the standard
main()function of any Kotlin application. Its primary purpose is to start up the underlying Netty server.The second function, named
module(), is the extension function referenced fromapplication.yaml. This function will be called automatically as the server starts up. In this case, all it does is invoke another module, namedconfigureRouting().The implementation of
configureRouting()can be found inRouting.kt:fun Application.configureRouting() { routing { get("/") { call.respondText("Hello World!") } } }Again, note that this is an extension function of the
Applicationclass.This sets up a single route for the application. This route handles GET requests for a relative URL of “/” (in effect, the application’s ‘home page’). The response issued for such a request is to send back some plain text content, the message
Hello World!The variable named
callreferences an object of typeRoutingCall. You can invoke various methods on this object in order to have the server deliver different types of response to the client that made the request.In this case, the server responds with plain text, but you can also use other functions here. For example,
respondHtml()will send dynamically constructed HTML,respondTemplate()will render the response using a template engine, andrespondBytes()will send binary data generated by the application.
Building & Running
-
Use this command to build the application:
./amper build -
Now run the server like this:
./amper runYou should see a couple of logging messages appear in the terminal, telling you that the application has started up and giving you a URL you can use to interact with it.
In a web browser, visit
http://0.0.0.0:8080You should see
Hello Worldappear in the browser window. -
Open another terminal window and go back to the directory where you previously installed httpx. In this directory, activate the virtual environment and then run the httpx tool with
httpx -v http://0.0.0.0:8080This will show you the full details of the GET request issued by httpx, and the response issued by the Ktor application.
-
Finally, return to the terminal window in which you ran the server, and terminate it by pressing
Ctrl+C.
-
The script is the file named
amper(oramper.batif you are using Windows). ↩