Vertx X Kotlin Coroutine Superset

A library that provides annotations handled by a Kotlin Symbol Processor with the purpose of speeding up Vertx x Kotlin Coroutine projects development time.

Provided annotations are capable of generating code for both HTTP and Vertx event bus handlers.

Summary

  1. Overview
  2. Usage
  3. Available annotations

Usage

Using gradle :

Kotlin Symbol Processors are supported by gradle

// build.gradle.kts
plugins {
    id("com.google.devtools.ksp")
    ...
}

dependencies {
    compileOnly("com.gabzz01:vertxgsuperset:1.0.0")
    ksp("com.gabzz01:vertxgsuperset:1.0.0")
    ...
}

Using Maven

Maven does not support KSP at the time this README is being written but a workaround is possible using the following extension https://github.com/Dyescape/kotlin-maven-symbol-processing

As stated in the linked extension repository, you may use following configuration to enable Kotlin Symbol Processing :

// pom.xml
<dependencies>

    <dependency>
        <groupId>io.vertx</groupId>
        <artifactId>vertx-core</artifactId>
        <version>${vertx.version}</version>
    </dependency>
    <dependency>
        <groupId>io.vertx</groupId>
        <artifactId>vertx-web</artifactId>
        <version>${vertx.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gabzz01.vertxgsuperset</groupId>
        <artifactId>vertxgsuperset</artifactId>
        <version>1.0.0</version>
    </dependency>
    ...
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-plugin</artifactId>
            <version>${kotlin.version}</version>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <compilerPlugins>
                    <compilerPlugin>ksp</compilerPlugin>
                </compilerPlugins>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>com.dyescape</groupId>
                    <artifactId>kotlin-maven-symbol-processing</artifactId>
                    <version>${ksp.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.gabzz01.vertxgsuperset</groupId>
                    <artifactId>vertxgsuperset</artifactId>
                    <version>1.0.0</version>
                </dependency>
            </dependencies>
        </plugin>
        ...
    </plugins>
</build>

Overview

Coroutine Http Handlers

Following code :

package com.test

@HttpController("/book")
class BookController {

    @CoroutineGetHandler
    suspend fun getAll(): List<Book> {
        // function implementation...
        return emptyList()
    }

    @CoroutinePostHandler
    suspend fun create(@RequestBodyParam book: Book): Book {
        // function implementation...
        return Book()
    }

    @CoroutinePutHandler("/:bookId")
    suspend fun updateById(
        @PathParam("bookId") bookId: Int,
        @RequestBodyParam updatedBook: Book,
        @QueryParam("ignoreNullFields") ignoreNullFields: Boolean
    ) {
        // function implementation...
    }

    @CoroutineDeleteHandler("/:bookId")
    suspend fun deleteById(@PathParam("/:bookId") bookId: Int ) {
        // function implementation...
    }
}

Would result in the generation of the underneath code :

package com.test

import io.vertx.core.json.Json
import io.vertx.ext.web.Router

class BookControllerWrapper(private val controller: BookController, router: Router) {

	init {

		router.get("/book").handler {
			GlobalScope.launch {
				val var0 = controller.getAll()
				it.response().end(Json.encodePrettily(var0))
			}
		}

		router.post("/book").handler {
			GlobalScope.launch {
				val var0 = it.getBodyAsJson().mapTo(com.test.Book::class.java)
				val var1 = controller.create(var0)
				it.response().end(Json.encodePrettily(var1))
			}
		}

		router.put("/book/:bookId").handler {
			GlobalScope.launch {
				val var0 = it.pathParam("bookId")?.toInt()
				val var1 = it.getBodyAsJson().mapTo(com.test.Book::class.java)
				val var2 = it.queryParams().get("ignoreNullFields")?.toBoolean()
				controller.updateById(var0, var1, var2)
				it.response().end()
			}
		}

		router.delete("/book/:bookId").handler {
			GlobalScope.launch {
				val var0 = it.pathParam("/:bookId")?.toInt()
				controller.deleteById(var0)
				it.response().end()
			}
		}

	}
}

GitHub

View Github