/kairo

Application framework built for Kotlin

Primary LanguageKotlinApache License 2.0Apache-2.0

Kairo

Kairo is an application framework built for Kotlin.

Project information

Major dependencies

  • Gradle 8.10
  • Kotlin 2.0
  • Java 21
  • Ktor 3.0
  • Guice 7.0
  • Jackson 2.18

Style guide

  • Product terminology: Treat Kairo Features and Servers as proper nouns (the first letter should be capitalized).

See the style guide for more.

Chores

See chores.

Modules

Kairo is split up into several separate modules. You will need a number of these. Each module falls into one of 3 categories:

  1. Common modules: These are intended for your use. You will use some or all of these. API stability is guaranteed.
  2. Optional modules: You may use these modules, but they won't always be necessary. API stability is guaranteed.
  3. Internal modules: These are only intended for internal use. Use them at your own risk; API stability is not guaranteed.

Common modules

Core modules:

  • kairo-server: A Server is an application that runs a set of Features.
  • kairo-feature: Features are Kairo's main building block.
  • kairo-logging: Logging uses the kotlin-logging interface, which should be configured to use Apache Log4j2 under the hood.
  • kairo-config: Home of ConfigLoader, which loads configs for Kairo Servers from YAML files. Includes support for config extension and application, as well as various sources.
  • kairo-serialization: Uses Jackson. to handle JSON, YAML, and even XML serialization.
  • kairo-testing: A convenient testing library which includes some helpful test dependencies.
  • kairo-util: Some useful utilities.

Feature modules:

Optional modules

  • kairo-alternative-money-formatters: Contains alternative non-default money formatters for serialization.
  • kairo-closeable: KairoCloseable is similar to Java's Closeable, but it supports coroutines.
  • kairo-darb: Home of DarbEncoder, which encodes a list of booleans into a Dense-ish Albeit Readable Binary (DARB) string.
  • kairo-date-range: Library for date range types.
  • kairo-dependency-injection: Makes Guice available, along with some utilities to make its use more idiomatic.
  • kairo-exception: Base classes representing exceptions that Kairo knows how to handle. This is primarily used by kairo-rest-feature.
  • kairo-mdc: Adds support for mapped diagnostic context (MDC), which is the JVM's way of adding context to log lines.
  • kairo-money: The Money type is provided by JSR-354.
  • kairo-protected-string: ProtectedString represents a string value that should not be logged or otherwise exposed.
  • kairo-reflect: This is a wrapper for Kotlin's reflection library that also includes some reflection-related utilities.
  • kairo-rest-client: A thin wrapper around Ktor's HttpClient.
  • kairo-transaction-manager: The Kairo TransactionManager offers explicit automatic handling of transactions that span multiple systems.
  • kairo-updater: A utility library for updating existing entities that supports Optionals to differentiate between null and undefined from the frontend.

Internal modules

  • kairo-command-runner: CommandRunner runs shell commands. It delegates to Java's built-in way of doing this, but uses an abstract class for testability.
  • kairo-environment-variable-supplier: EnvironmentVariableSupplier supplies environment variables. It delegates to Java's built-in way of doing this, but uses an abstract class for testability.
  • kairo-gcp-secret-supplier: GcpSecretSupplier supplies GCP secrets. It delegates to the GCP Secret Manager SDK, but uses an abstract class for testability.
  • kairo-google-common: This common library contains adaptive utils for integrating Google's GCP libraries with Kotlin and Kairo.

Getting started

The best way to get started is to refer to the kairo-sample repository.

Releasing

  1. Familiarize yourself with semantic versioning.
  2. Create a new branch called release/X.Y.Z.
  3. Bump the version in kairo-publish.gradle.kts.
  4. Commit "Release X.Y.Z".
  5. Create and merge a PR "Release X.Y.Z". No description is necessary.
  6. Draft a new release. Create a new tag vX.Y.Z. Title "Kairo X.Y.Z". Generate and prefix release notes.
  7. Manually run ./gradlew publish on main after merging.