Skip to content

Getting Started

Vladislav.Tankov edited this page Jun 2, 2020 · 17 revisions

In this short tutorial we will overview the steps of creating a Kotless-based application.

We will use Kotless DSL for demonstration purposes. Still, Ktor and Spring Boot differences will be mentioned.

Preliminaries

To use Kotless in your project and run it locally, you need:

  • Kotlin version 1.3.72+.

To deploy the application, you need:

  • Administrative access to AWS account (e.g. profile in .aws/.credentials);
  • S3 bucket to store Kotless-related artifacts.

If you also want to set a custom name for your application, you need:

  • Route53 DNS zone to create DNS name for the application;
  • ACM certificate for the DNS name at US-EAST-1 (N. Virginia).

Setting up Gradle project

First of all, you need to set up Gradle for your project. Kotless uses Gradle tasks to prepare deployment environment, generate deployment code, prepare a jar and deploy it to cloud provider.

You need to apply a plugin to project at build.gradle.kts:

//Imports needed for this example
import io.kotless.plugin.gradle.dsl.Webapp.Route53
import io.kotless.plugin.gradle.dsl.kotless

//Group may be used by Kotless DSL to reduce number of introspected classes by package
//So, don't forget to set it
group = "org.example"
version = "0.1.0"


plugins {
    //Version of Kotlin should be 1.3.72+
    kotlin("jvm") version "1.3.72" apply true

    id("io.kotless") version "0.1.5" apply true
}

To use Kotless DSL in a project, you need to set up a maven repository with DSL and add the necessary dependency:

repositories {
    jcenter()
}
dependencies {
    implementation("io.kotless", "lang", "0.1.5")

    //or for Ktor (Note, that Kotless bundles version 1.3.2)
    //implementation("io.kotless", "ktor-lang", "0.1.5")

    //or for Spring Boot (Note, that Kotless bundles version 2.3.0.RELEASE)
    //implementation("io.kotless", "spring-boot-lang", "0.1.5")
}

If you don't have an AWS account — stop here. Now you can use local task to run the application locally and debug it. If you want to continue — create AWS account following simple instruction by Hadi Hariri.

If you have an AWS account and want to perform the real deployment — let's set up everything for it! It's rather simple:

kotless {
    config {
        bucket = "kotless.s3.example.com"

        terraform {
            profile = "example"
            region = "us-east-1"
        }
    }

    webapp {
        //Optional parameter, by default technical name will be generated
        route53 = Route53("kotless", "example.com")
    }
}

Writing dynamic route

Let's write your first dynamic route.

In Kotless terminology, a "dynamic route" is an HTTP route processed by a lambda. In contrast with it, a "static route" is an HTTP route mapped to an S3 object.

Creating dynamic route is relatively simple. This code snippet for Kotless DSL will create a route at HTTP path /, which will print "Hello world!".

@Get("/")
fun main() = "Hello world!"

Note that dynamic route function may have parameters. Parameters will be taken from the URL and body (if presented) and deserialized into the parameters of the function. Moreover, the result of the function will also be serialized to the HTTP response automatically.

In case you need full control over the HTTP response, you may return HttpResponse object, which will be passed to ApiGateway without any changes.

For Ktor, the equivalent of the dynamic route is routing. Here is a simple example:

class Server : Kotless() {
    override fun prepare(app: Application) {
        app.routing {
            get("/") {
                call.respondText { "Hello World!" }
            }
        }
    }
}

For Spring Boot, the equivalent of the dynamic route is @GetMapping/@@PostMapping/... or @RequestMapping. Here is a simple example:

@SpringBootApplication
open class Application : Kotless() {
    override val bootKlass: KClass<*> = this::class
}

@RestController
object Pages {
    @GetMapping("/")
    fun main() = "Hello World!"
}

Adding statics to your application

Most of the real-world applications contain static resources, e.g. CSS and JS files. Serving static resources with lambdas is a very wasteful spending of resources, so Kotless proposes a solution — static resources mapped directly to S3.

This code snippet for Kotless DSL will create a route at HTTP path /file.css with file example.css

@StaticGet("/file.css", MimeType.CSS)
val exampleCss = File("example.css")

Note that the file will be resolved against staticsRoot set in Gradle configuration.

For Ktor, the equivalent of the static route is the static feature in routing. Here is a simple example:

class Server : Kotless() {
    override fun prepare(app: Application) {
        app.routing {
            static {
                file("file.css", "example.css")
            }
        }
    }
}

For Spring Boot, static routes will be taken from static folder of resources as Spring Boot do during normal work.

Running application locally

If you want to check that your application works as you expect or debug it, you can simply run it locally.

Execute local task in Gradle and Kotless will start an HTTP server, AWS emulation (if enabled), and cron scheduler to execute your application the same way as it would be in AWS.

Deploying application to AWS

Finally, you need to deploy your Kotless-based application to AWS. Check all the preliminary conditions are fulfilled and execute deploy task in Gradle.

Kotless will download Terraform, generate deployment code, pack lambda, and, in the end, deploy the application to AWS.

As soon as the deployment is completed, your application will start serving requests at the Route53 DNS name you have assigned to it or at technical name that was generated automatically.