Introduction

API Viaduct is a serverless RESTful API and router written in Kotlin for AWS Lambda.

Inspired by my earlier project Cantilever, I wanted to create a more lightweight and flexible API framework for AWS Lambda. This project is a work in progress and is not yet ready for production use.

RESTful routes are defined using a Kotlin DSL, and the library uses Kotlinx Serialization for JSON (de)serialization. The project is built using Gradle and the AWS SDK for Kotlin.

The library supports route grouping, authentication, all the main REST methods, and more. There is a rudimentary OpenAPI specification generator, and middleware or filters will be added in the future. While the router defaults to JSON, it is possible to specify other content types such as text, YAML or any others supported by kotlinx.serialization.

The library does not currently support multipart form uploads, nor URL query parameters. Nonetheless, it successfully serves my Cantilevers web editor.

Example

class MyRouter : LambdaRouter() {
    override val router = lambdaRouter {

        // a simple get request handler
        get("/hello") { _: Request<Unit> ->
            Response.OK("Hello, world!")
        }
        // a simple POST request handler, expecting a JSON body for a data class of type 'Thingy'
        post("/new") { req: Request<Thingy> ->
            val body = req.body
            Response.OK("You sent: ${body.name}")
        }

        // route grouping
        group("/group") {
            get("/test", handler = { _: Request<Unit> -> Response.ok(body = "This route was /group/test") }).supplies(
                MimeType.plainText
            )
        }
        
        // basic authentication support (there is an authentication interface to implement)
        auth(BasicFakeAuthorizer()) {
            get("/secure") { _: Request<Unit> ->
                Response.ok("Secure route")
            }.supplies(MimeType.plainText)
        }
    }
}

Lambda cold start

This project builds AWS lambda functions with a Java (JVM) runtime. This comes with an inherent downside - the lambda cold start problem. Put simply, the first request to this API will be slow as AWS boots up the java virtual machine. Subsequent requests will respond quickly, but with inactivity AWS will stop the JVM again.

I'd like to investigate using GraalVM to address this problem (essentially, compiling to native machine code), but that is a while away.