Code-First Configuration Library for Kotlin

David Ohana
The Startup
Published in
2 min readOct 15, 2020

GitHub repo: https://github.com/davidohana/kofiko-kotlin

Preface

Kotlin and Python are my favorite programming languages. After publishing Kofiko configuration library for Python, I decided to work on a port of it for Kotlin. Actually the porting to Kotlin took significantly more effort, for many reasons. I wanted to introduce better extensibility architecture this time, I wanted the library to support more formats, and also due to many conceptual differences between Kotlin and Python. For example, Kotlin Annotations can contain metadata only, and Python Decorators can contain logic.

Other challenges involved were how to discover configuration objects, how to design a fluent API for adding configuration layers (providers), and a lot of reflection work.

Though I tried to keep the library clean from any external dependency, I finally settled on a single dependency in the well-known jackson.core (ObjectMapper) library, in order to be able to reuse string parsing ability of Jackson without having to write many type converters.

Kofiko (Kode-First Konfiguration) is a lightweight, simple and minimal boilerplate configuration library for Kotlin.

  • Supported formats: .json, .ini, .properties, .env (more to come)
  • Layered (cascading) and extensible design allows overriding the configuration from environment variables, command-line arguments, JVM system properties (-D), Java Maps in any precedence order you like.

Demo

Define application configuration as Kotlin classes/objects:

Each config section is represented by a class / object so that configuration consumers may receive only the configuration of interest. Configuration options should be declared as var properties (read/write) with baked-in defaults. By using Kotlin object, you may easily access configuration as a singleton without injection. However, instances of configuration classes may be configured as well.

Override default values at run-time:

For example, from a JSON file:

{
"database": {
"user": "davidoh",
"db_size_limits": {
"logs": 1,
"events": 120
}
}
}

or using env. vars:

DATABASE_user=davidoh \
DATABASE_password=reallysecret! \
DATABASE_endpoints=prod1,prod2 \
LOG_level=WARNING \
DATABASE_DB_SIZE_LIMITS=logs:5,events:120 \
java -cp my_app.jar

Kofiko uses out-of-the-box (configurable) conventions to search for matching configuration entries, looking for lowercase, uppercase, camel-case, snake-case, kebab-case matches.

Initialize Kofiko with the desired configuration sources:

Program output:

LogConfig.level was changed from <INFO> to <WARNING> by IniConfigProvider
WARNING: Hello Kofiko
DatabaseConfig.user was changed from <default_user> to <davidoh> by IniConfigProvider
DatabaseConfig.password was changed from <[hidden]> to <[hidden]> by IniConfigProvider
DatabaseConfig.endpoints was changed from <[http://localhost:1234]> to <[prod1, prod2]> by IniConfigProvider
DatabaseConfig.dbSizeLimits was changed from <{alerts=50, logs=200}> to <{alerts=2, logs=1}> by JsonConfigProvider
Database user is davidoh

Kofiko can print/log the effective configuration overrides, omitting secret info like passwords.

The source code for Kofiko is available on GitHub under the Apache-2.0 license.
For further details, please refer to the GitHub repository of the project at https://github.com/davidohana/kofiko-kotlin.

--

--