Estimated reading time: 2 minutes
You can develop your own features and reuse them across your Ktor applications, or share with the community. Typical feature has the following structure:
class CustomFeature(configuration: Configuration) {
val prop = configuration.prop // get snapshot of config into immutable property
class Configuration {
var prop = "value" // mutable property
}
// implement ApplicationFeature in a companion object
companion object Feature : ApplicationFeature<ApplicationCallPipeline, CustomFeature.Configuration, CustomFeature> {
// create unique key for the feature
override val key = AttributeKey<CustomFeature>("CustomFeature")
// implement installation script
override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): CustomFeature {
// run configuration script
val configuration = CustomFeature.Configuration().apply(configure)
// create a feature
val feature = CustomFeature(configuration)
// intercept a pipeline
pipeline.intercept(…) {
// call a feature
}
return feature
}
}
}
CustomFeature
is a feature instance class, which should be immutable to avoid unintended side-effects in a highly
concurrent environment. Feature implementation should be thread-safe as it will be called from multiple threads.
Configuration
instance is handed to the user installation script and allows for feature configuration.
Feature
companion object conforms to Ktor API and wires things together.
Feature can be installed with the standard install
function:
fun Application.main() {
install(CustomFeature) { // Install a custom feature
prop = "Hello" // configuration script
}
}
See complete example in a custom feature sample