/vertx3-lang-kotlin

Vert.x 3 Kotlin bindings

Primary LanguageKotlin

Disclaimer

vertx3-lang-kotlin is going to be moved into vert.x organization: https://github.com/vert-x3/vertx-lang-kotlin/

Vert.x 3 Kotlin bindings

Download Build Status Kotlin

This module provides Kotlin language bindings including DSL and extension functions for vert.x 3 and provides better Kotlin programming experience

Getting started (Gradle)

Please refer to Kotlin Using Gradle for Kotlin Gradle configuration before.

When you have kotlin configured properly add the following repository

repositories { maven { url "http://dl.bintray.com/cy6ergn0m/maven" } }

then add dependency

dependencies {
    compile 'org.jetbrains.kotlinx:vertx3-lang-kotlin:0.0.+'
}

See Kotlin vert.x 3 Gradle project example

Getting started (Maven)

Please refer to Kotlin Using Maven for Kotlin Maven configuration before setup vertx3-lang-kotlin.

Once you get it well configured you can proceed.

First of all you need additional repository added:

<repository>
    <id>bintray-cy</id>
    <name>bintray-cy</name>
    <url>http://dl.bintray.com/cy6ergn0m/maven</url>
</repository>

After that you can add dependency

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>vertx3-lang-kotlin</artifactId>
    <version>[0.0.4,0.1.0)</version>
</dependency>

Run example application

./gradlew runExample

after that open http://localhost:8084/testit.html and try to play with queries and the source code.

Examples

Simple REST service

fun main(args: Array<String>) {
    DefaultVertx {
        httpServer(8084) { request ->
            bodyJson {
                object_(
                    "title" to "Hello, my remote peer",
                    "message" to "You address is ${request.remoteAddress().host()}"
                )
            }
        }
    }
}

Simple echo socket server

class EchoSocket : AbstractVerticle() {
    override fun start() {
        netServer(9094) { client ->
            client.startPumpTo(client)
        }
    }
}

HTTP routing example (non-apex)

import io.vertx.kotlin.lang.*

fun main(args: Array<String>) {
    DefaultVertx {
        httpServer(8084, "0.0.0.0", Route {
            GET("/path") { request ->
                bodyJson {
                    "field1" to "test me not"
                }
            }

            otherwise {
                setStatus(404, "Resource not found")
                body {
                    write("The requested resource was not found\n")
                }
            }
        })
    }
}

HTTP ETag and on-disk cache support

import io.vertx.kotlin.lang.*
import io.vertx.kotlin.lang.http.*
import io.vertx.kotlin.lang.json.*

fun main(args: Array<String>) {
    DefaultVertx {
        val cache = Cache(this, "target/cache")

        httpServer(9091) { request ->
            contentType("application/json")
            setChunked(true)

            val params = request.params().toList().groupBy { it.key }.mapValues { it.value.map { it.value } }

            request.withHashEtag(params) {
                request.withHashedCache(cache, params) { end ->
                    setTimer(2000L) {
                        writeJson {
                            object_(
                                    "a" to 1,
                                    "b" to array_("x", "y", "z"),
                                    "params" to array_(request.params())
                            )
                        }
                        end()  // NOTE you MUST call it at end of with*Cache lambda
                    }
                }
            }
        }
    }
}

Cached page to be updated only when something changes

    request.withHashedCache(cache, blog.lastPost?.id) { end ->
        writeJson {
            object_(
                    "title" to blog.displayName,
                    "lastPostTitle" to blog.lastPost?.title
            )
        }
        end()
    }

Shopping cart ETags example:

val cart = session.getCart()

request.withHashedEtag(cart.items.map { it.id to it.amount }) {
  // generate page
}

In this example we have ETag based on cart content so if user has no any changes in the cart then the page will not be generated if user already have valid version in cart's page.

Both on-disk caching and ETag configured properly may significantly reduce web server performance. However you have to choose among ETag/Cache and think of valid keys to be used. The general recommendation is to use on-disk cache for public pages (available to all users and have the same content) and etags for everything possible.

🔴 Note that on-disk cache is never purged automatically so you have to do it your own.

🔴 Notice that you can't set any headers/cookies/etc in a cached lambda. If you need something special you have to specify it before withCache block

On-disk invalidation

You can optionally provide your invalidation strategy by passing predicate function: this function will be called for each request and receive cache file name (you can use it e.g. to check file modification date or exam it's content) and two lambdas onValid and onInvalid: you must to call one of them according to your decision.

More examples

See more examples. Some of them just copied from original examples at vert.x repo.