1. Overview
bootique-kotlin
contains following modules:
-
Kotlin APIs and extensions for Bootique;
-
Kotlin Script Configuration Module;
-
Configuration and Extensions for Bootique Modules;
-
JacksonService
which providesObjectMapper
with enabledKotlinModule
.
2. TL;DR;
-
Use
KotlinBootique
instead ofBootique
; -
Use
KotlinModule
instead ofModule
, you can useKotlinModule
withConfigModule
(just inherit both); -
Use
KotlinBQModuleProvider
instead ofBQModuleProvider
; -
Use extensions defined in Extensions.kt;
-
Use
bootique-kotlin-configuration
module to benefit from configuration written in Kotlin. -
Use
bootique-kotlin-jackson
to getObjectMapper
withKotlinModule
.
3. Getting started
Kotlin 1.4.10 used in project.
Add dependency on needed parts in your build.gradle
, or pom.xml
:
// Kotlin Extensions for Bootique
compile("io.bootique.kotlin:bootique-kotlin:2.0.1")
// Kotlin Configuration Module
compile("io.bootique.kotlin:bootique-kotlin-config:2.0.1")
// Kotlin Configuration Module
compile("io.bootique.kotlin:bootique-kotlin-jackson:2.0.1")
// Kotlin Configuration and Extensions for Jetty. Also this adds dependency to bootique-jetty module.
compile("io.bootique.kotlin:bootique-kotlin-jetty:2.0.1")
// Kotlin Configuration and Extensions for Logback. Also this adds dependency to bootique-logback module.
compile("io.bootique.kotlin:bootique-kotlin-logback:2.0.1")
// Kotlin Configuration and Extensions for $moduleName$. Also this adds dependency to bootique-$moduleName$ module.
compile("io.bootique.kotlin:bootique-kotlin-$moduleName$:2.0.1")
bootique-kotlin-config: org.jetbrains.kotlin:kotlin-scripting-jvm-host bootique-kotlin-jackson: org.jetbrains.kotlin:kotlin-reflect If you use different kotlin version, it’s much simpler to include these libraries with proper version, instead of excluding library version of them and then including again. |
If you’d like to use snapshot versions, you have to add bootique snapshot repository:
https://oss.sonatype.org/content/repositories/snapshots
For example in gradle it can be done this way:
repositories {
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") }
}
And then use snapshot version: 2.0.B1-SNAPSHOT.
4. Bootique
4.1. KotlinBootique
bootique-kotlin
provides replacement for Bootique
class - KotlinBootique
:
fun main(args: Array<String>) {
KotlinBootique(args)
.module(ApplicationModule::class)
.exec()
.exit()
}
So no need for extensions for Bootique
class, KotlinBootique
provides best experience for developing Bootique apps with Kotlin.
4.2. KotlinBQModuleProvider
KotlinBQModuleProvider
- interface to implement in Bootique Kotlin application instead of BQModuleProvider
.
class ApplicationModuleProvider : KotlinBQModuleProvider {
override val module = ApplicationModule()
override val overrides = listOf(BQCoreModule::class)
override val dependencies = listOf(KotlinConfigModule::class)
}
You can see how declarative become module provider.
4.3. ConfigurationFactory
// Using Java Api
configurationFactory.config(SampleFactory::class.java, "sample")
// With Extension
configurationFactory.config(SampleFactory::class, "sample")
// With Extension, reified generics
configurationFactory.config<SampleFactory>("sample")
// Type Inference
@Singleton
@Provides
fun createAppConfiguration(configurationFactory: ConfigurationFactory): SampleFactory {
return configurationFactory.config/* No Type Here */(configPrefix)
}
4.4. Adding command
Straightforward and easy to use extension for contributing commands.
BQCoreModule
.extend(binder)
.addCommand(ApplicationCommand::class)
4.5. Default command
Also extension for setDefaultCommand
available.
BQCoreModule
.extend(binder)
.setDefaultCommand(ApplicationCommand::class)
4.6. Bootique DI
4.6.1. KotlinModule
bootique-kotlin
introduces new module interface to use with kotlin: KotlinModule
class ApplicationModule : KotlinModule {
override fun configure(binder: KotlinBinder) {
binder.bind(ShareCountService::class).to(DefaultShareCountService::class).asSingleton()
binder.bind(HttpClient::class).to(DefaultHttpClient::class).asSingleton()
}
}
4.6.2. Extensions
There are few functions to help work with TypeLiteral
and Key
.
// TypeLiteral
typeLiteral<Array<String>>()
// Key
key<List<Callable<A>>>()
5. Configuration Module
Using Kotlin Script for a configuration is really simple:
-
Create script
-
Override
ConfigurationFactory
5.1. Using Kotlin Script file
Configuration with Kotlin can be defined in Kotlin Script file:
import io.bootique.kotlin.config.modules.httpConnector
import io.bootique.kotlin.config.modules.jetty
jetty {
httpConnector {
port = 4242
host = "0.0.0.0"
}
}
5.2. Enable Kotlin Script Configuration
Enable Kotlin Script Configuration in Bootique with extension:
fun main(args: Array<String>) {
KotlinBootique(args)
.withKotlinConfig() // Extension function
.autoLoadModules()
.exec()
.exit()
}
Using BQModuleProvider
:
fun main(args: Array<String>) {
KotlinBootique(args)
.module(KotlinConfigModuleProvider())
.autoLoadModules()
.exec()
.exit()
}
You can pass this file as always to bootique:
./bin/application --config=classpath:config.bq.kts --server
It’s even support multiple files (each file contains map of configs):
./bin/application --config=classpath:config.bq.kts --config=classpath:config1.bq.kts --server
That’s it! You get autocomplete in IDE, and code for a configuration!
6. Bootique Jetty
Define empty config:
jetty {
}
Use autocompletion to define configuration.
Use httpConnector/httpsConnector
extensions to define connectors:
jetty {
httpConnector {
port = 4242
host = "192.168.0.1"
responseHeaderSize = 42
requestHeaderSize = 13
}
}
7. Bootique Logback
Define logback configuration:
addConfig("log", logbackContextFactory(
logFormat = "[%d{dd/MMM/yyyy:HH:mm:ss}] %t %-5p %c{1}: %m%n",
useLogbackConfig = false,
debugLogback = false,
level = LogbackLevel.warn,
loggers = mapOf(
logger(LogbackModuleTest::class, LogbackLevel.error),
logger("TestLogger", LogbackLevel.trace)
),
appenders = listOf(
consoleAppender(
logFormat = "[%d{dd/MMM/yyyy:HH:mm:ss}] %t %-5p %c{1}: %m%n",
target = ConsoleTarget.stderr
),
fileAppender(logFormat, "abc", timeBasedPolicy(
fileNamePattern = "Abc_%d",
totalSize = "2m",
historySize = 1
))
)
))
Use function for retrieving logger for class:
val logger = logger<SomeService>()
Or if class is generic:
val logger = logger<SomeService<*>>()
8. Bootique Undertow
Define undertow configuration:
addConfig("undertow", undertowFactory(
httpListeners = listOf(
httpListener(1337, "127.0.0.1")
),
workerThreads = 42
))