Ktor server core module for iOS ARM64 target providing essential server-side functionality for building asynchronous web applications and microservices in Kotlin Multiplatform
—
Application configuration system supporting multiple formats and sources with hierarchical merging capabilities. Provides flexible configuration management for Ktor applications with support for environment variables, config files, and programmatic configuration.
Core interface for accessing hierarchical configuration data.
/**
* Represents application config node with hierarchical structure
*/
interface ApplicationConfig {
/** Get a property value, throws if missing */
fun property(path: String): ApplicationConfigValue
/** Get a property value or null if missing */
fun propertyOrNull(path: String): ApplicationConfigValue?
/** Get a nested config section */
fun config(path: String): ApplicationConfig
/** Get a list of config sections */
fun configList(path: String): List<ApplicationConfig>
/** Get all keys at this config level */
fun keys(): Set<String>
/** Convert config to a map representation */
fun toMap(): Map<String, Any?>
}Interface for accessing typed configuration values with conversion support.
/**
* Represents a configuration value with type information
*/
interface ApplicationConfigValue {
/** The type of this configuration value */
val type: Type
/** Get value as string */
fun getString(): String
/** Get value as list of strings */
fun getList(): List<String>
/** Get value as map */
fun getMap(): Map<String, Any?>
/** Get value converted to specified type */
fun getAs(type: TypeInfo): Any?
/**
* Type enumeration for configuration values
*/
enum class Type {
NULL,
SINGLE,
LIST,
OBJECT
}
}Mutable configuration implementation backed by hash map for programmatic configuration.
/**
* Mutable application config backed by hash map
*/
open class MapApplicationConfig : ApplicationConfig {
/** Set a single string value */
fun put(path: String, value: String)
/** Set multiple string values */
fun put(path: String, values: Iterable<String>)
/** Remove a configuration value */
fun remove(path: String)
/** Check if path exists */
fun containsKey(path: String): Boolean
/** Clear all configuration */
fun clear()
}System for loading configuration from various sources.
/**
* Interface for loading application configuration
*/
interface ConfigLoader {
/** Load configuration from specified path */
fun load(path: String?): ApplicationConfig?
companion object {
/** Load configuration using default loaders */
fun load(path: String? = null): ApplicationConfig
}
}Utilities for combining multiple configuration sources with precedence rules.
/**
* Merge this configuration with another, other takes precedence
*/
fun ApplicationConfig.mergeWith(other: ApplicationConfig): ApplicationConfig
/**
* Merge this configuration with another, this takes precedence
*/
fun ApplicationConfig.withFallback(other: ApplicationConfig): ApplicationConfigException classes for configuration-related errors.
/**
* Thrown when application is misconfigured
*/
class ApplicationConfigurationException(message: String, cause: Throwable? = null) : Exception(message, cause)import io.ktor.server.application.*
import io.ktor.server.config.*
fun Application.configureFromConfig() {
val config = environment.config
// Access simple properties
val serverPort = config.property("server.port").getString().toInt()
val serverHost = config.property("server.host").getString()
val debugMode = config.propertyOrNull("debug")?.getString()?.toBoolean() ?: false
// Access nested configuration
val databaseConfig = config.config("database")
val dbUrl = databaseConfig.property("url").getString()
val dbDriver = databaseConfig.property("driver").getString()
// Access list configuration
val allowedHosts = config.property("security.allowedHosts").getList()
// Access complex nested structures
val features = config.configList("features")
features.forEach { featureConfig ->
val name = featureConfig.property("name").getString()
val enabled = featureConfig.property("enabled").getString().toBoolean()
println("Feature $name: $enabled")
}
}import io.ktor.server.config.*
fun createProgrammaticConfig(): ApplicationConfig {
val config = MapApplicationConfig()
// Set single values
config.put("server.port", "8080")
config.put("server.host", "localhost")
config.put("debug", "true")
// Set list values
config.put("security.allowedHosts", listOf("localhost", "127.0.0.1", "::1"))
// Set nested values using dot notation
config.put("database.url", "jdbc:h2:mem:test")
config.put("database.driver", "org.h2.Driver")
config.put("database.user", "sa")
config.put("database.password", "")
return config
}import io.ktor.server.config.*
fun mergeConfigurations(): ApplicationConfig {
// Load base configuration from file
val baseConfig = ConfigLoader.load("application.conf")
// Create environment-specific overrides
val envConfig = MapApplicationConfig().apply {
put("server.port", System.getenv("PORT") ?: "8080")
put("database.url", System.getenv("DATABASE_URL") ?: "jdbc:h2:mem:dev")
}
// Create development-specific settings
val devConfig = MapApplicationConfig().apply {
put("debug", "true")
put("logging.level", "DEBUG")
}
// Merge configurations with precedence
// envConfig overrides baseConfig, devConfig overrides both
return baseConfig
.mergeWith(envConfig)
.mergeWith(devConfig)
}import io.ktor.server.config.*
// Extension functions for common configuration patterns
val ApplicationConfig.serverPort: Int
get() = property("server.port").getString().toInt()
val ApplicationConfig.serverHost: String
get() = property("server.host").getString()
val ApplicationConfig.isDebugMode: Boolean
get() = propertyOrNull("debug")?.getString()?.toBoolean() ?: false
val ApplicationConfig.databaseUrl: String
get() = config("database").property("url").getString()
fun ApplicationConfig.getStringList(path: String): List<String> =
property(path).getList()
fun ApplicationConfig.getOptionalString(path: String): String? =
propertyOrNull(path)?.getString()
fun ApplicationConfig.getOptionalInt(path: String): Int? =
propertyOrNull(path)?.getString()?.toIntOrNull()
// Usage
fun Application.configureWithExtensions() {
val config = environment.config
val port = config.serverPort
val host = config.serverHost
val debug = config.isDebugMode
val dbUrl = config.databaseUrl
val allowedOrigins = config.getStringList("cors.allowedOrigins")
val maxRequestSize = config.getOptionalInt("limits.maxRequestSize") ?: 1048576
}import io.ktor.server.config.*
fun createEnvironmentConfig(): ApplicationConfig {
val config = MapApplicationConfig()
// Database configuration from environment
config.put("database.url",
System.getenv("DATABASE_URL") ?: "jdbc:h2:mem:test")
config.put("database.user",
System.getenv("DB_USER") ?: "sa")
config.put("database.password",
System.getenv("DB_PASSWORD") ?: "")
config.put("database.maxPoolSize",
System.getenv("DB_POOL_SIZE") ?: "10")
// Server configuration from environment
config.put("server.port",
System.getenv("PORT") ?: "8080")
config.put("server.host",
System.getenv("HOST") ?: "0.0.0.0")
// Feature flags from environment
config.put("features.rateLimiting",
System.getenv("ENABLE_RATE_LIMITING") ?: "false")
config.put("features.caching",
System.getenv("ENABLE_CACHING") ?: "true")
// Logging configuration
config.put("logging.level",
System.getenv("LOG_LEVEL") ?: "INFO")
config.put("logging.appenders",
listOf("console", "file"))
return config
}import io.ktor.server.config.*
fun validateConfiguration(config: ApplicationConfig) {
try {
// Validate required properties exist
val requiredProperties = listOf(
"server.port",
"server.host",
"database.url",
"database.driver"
)
requiredProperties.forEach { path ->
config.property(path) // Will throw if missing
}
// Validate port is valid number
val port = config.property("server.port").getString().toInt()
require(port in 1..65535) { "Port must be in range 1-65535, got $port" }
// Validate database URL format
val dbUrl = config.property("database.url").getString()
require(dbUrl.startsWith("jdbc:")) { "Database URL must start with jdbc:" }
// Validate optional properties
config.propertyOrNull("server.ssl.enabled")?.let { ssl ->
if (ssl.getString().toBoolean()) {
config.property("server.ssl.keyStore") // Must exist if SSL enabled
config.property("server.ssl.keyStorePassword")
}
}
} catch (e: Exception) {
throw ApplicationConfigurationException("Configuration validation failed", e)
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-server-core-iosarm64