kotlin-app-config
navikt/copilot/skills/kotlin-app-config/SKILL.md
Sealed class-konfigurasjon for Kotlin-applikasjoner med miljøspesifikke innstillinger
Skill54 starsChanged 19 days ago
What's in it
- Kotlin Application Configuration Skill
- Sealed Class Configuration Pattern
- Using Configuration
- With Konfig Library
- Alternative: Sealed Interface Pattern (navikt/hotlibs)
- Benefits
---
name: kotlin-app-config
description: Sealed class-konfigurasjon for Kotlin-applikasjoner med miljøspesifikke innstillinger
license: MIT
compatibility: Kotlin application
metadata:
domain: backend
tags: kotlin configuration sealed-class environment
---
# Kotlin Application Configuration Skill
This skill provides patterns for type-safe environment configuration using Kotlin sealed classes.
## Sealed Class Configuration Pattern
```kotlin
sealed class Environment(
val name: String,
val databaseUrl: String,
val kafkaBrokers: String,
val azureAdIssuer: String
) {
data object Local : Environment(
name = "local",
databaseUrl = "jdbc:postgresql://localhost:5432/myapp",
kafkaBrokers = "localhost:9092",
azureAdIssuer = "http://localhost:8080/azuread"
)
data class Dev(
private val env: Map<String, String>
) : Environment(
name = "dev",
databaseUrl = env.getValue("DATABASE_URL"),
kafkaBrokers = env.getValue("KAFKA_BROKERS"),
azureAdIssuer = env.getValue("AZURE_OPENID_CONFIG_ISSUER")
)
data class Prod(
private val env: Map<String, String>
) : Environment(
name = "prod",
databaseUrl = env.getValue("DATABASE_URL"),
kafkaBrokers = env.getValue("KAFKA_BROKERS"),
azureAdIssuer = env.getValue("AZURE_OPENID_CONFIG_ISSUER")
)
companion object {
fun from(env: Map<String, String>): Environment {
return when (env["NAIS_CLUSTER_NAME"]) {
"dev-gcp" -> Dev(env)
"prod-gcp" -> Prod(env)
else -> Local
}
}
}
}
```
## Using Configuration
```kotlin
fun main() {
val env = Environment.from(System.getenv())
val dataSource = createDataSource(env.databaseUrl)
val kafkaProducer = createKafkaProducer(env.kafkaBrokers)
logger.info("Starting application in ${env.name} environment")
}
```
## With Konfig Library
```kotlin
import com.natpryce.konfig.*
data class AppConfig(
val database: DatabaseConfig,
val kafka: KafkaConfig,
val azure: AzureConfig
)
data class DatabaseConfig(
val url: String
)
data class KafkaConfig(
val brokers: String
)
data class AzureConfig(
val issuer: String
)
val config = EnvironmentVariables()
val appConfig = AppConfig(
database = DatabaseConfig(
url = config.getOrNull(Key("DATABASE_URL", stringType))
?: "jdbc:postgresql://localhost:5432/myapp"
),
kafka = KafkaConfig(
brokers = config.getOrNull(Key("KAFKA_BROKERS", stringType))
?: "localhost:9092"
),
azure = AzureConfig(
issuer = config.getOrNull(Key("AZURE_OPENID_CONFIG_ISSUER", stringType))
?: "http://localhost:8080/azuread"
)
)
```
## Alternative: Sealed Interface Pattern (navikt/hotlibs)
Production pattern from [navikt/hotlibs](https://github.com/navikt/hotlibs) supporting multiple cluster types:
```kotlin
sealed interface Environment {
val cluster: String
val tier: Tier
enum class Tier { TEST, LOCAL, DEV, PROD }
companion object {
private val all: List<Environment> = listOf(
TestEnvironment,
LocalEnvironment,
GcpEnvironment.DEV,
GcpEnvironment.PROD
)
val current: Environment by lazy {
val cluster = System.getenv("NAIS_CLUSTER_NAME")
all.find { it.cluster == cluster } ?: LocalEnvironment
}
}
}
sealed class DefaultEnvironment(
override val cluster: String,
override val tier: Environment.Tier
) : Environment
object TestEnvironment : DefaultEnvironment("test", Environment.Tier.TEST)
object LocalEnvironment : DefaultEnvironment("local", Environment.Tier.LOCAL)
enum class GcpEnvironment(
override val cluster: String,
override val tier: Environment.Tier
) : Environment {
DEV("dev-gcp", Environment.Tier.DEV),
PROD("prod-gcp", Environment.Tier.PROD)
}
```
```kotlin
data class DatabaseConfig(
val url: String,
val username: String,
val password: String
)
data class KafkaConfig(
val brokers: String,
val topic: String
)
data class AzureConfig(
val clientId: String,
val issuer: String,
val jwksUri: String
)
fun loadConfig(): AppConfig {
val config = ConfigurationProperties.systemProperties() overriding
EnvironmentVariables()
return AppConfig(
database = DatabaseConfig(
url = config[Key("database.url", stringType)],
username = config[Key("database.username", stringType)],
password = config[Key("database.password", stringType)]
),
kafka = KafkaConfig(
brokers = config[Key("kafka.brokers", stringType)],
topic = config[Key("kafka.topic", stringType)]
),
azure = AzureConfig(
clientId = config[Key("azure.client.id", stringType)],
issuer = config[Key("azure.issuer", stringType)],
jwksUri = config[Key("azure.jwks.uri", stringType)]
)
)
}
```
## Benefits
- **Type Safety**: Compile-time validation of configuration
- **Environment Separation**: Clear boundaries between local/dev/prod
- **Testability**: Easy to create test configurations
- **Documentation**: Configuration structure is self-documenting
More agent context in navikt/copilot
35 other files this repository gives its agents.
AGENTS.md
Copilot instructions
Skill
- ai-news-researchskills/ai-news-research/SKILL.md
- aksel-builderskills/aksel-builder/SKILL.md
- aksel-spacingskills/aksel-spacing/SKILL.md
- api-designskills/api-design/SKILL.md
- conventional-commitskills/conventional-commit/SKILL.md
- deliberate-ai-useskills/deliberate-ai-use/SKILL.md
- flyway-migrationskills/flyway-migration/SKILL.md
- jackson-3-migrationskills/jackson-3-migration/SKILL.md
- java-to-kotlinskills/java-to-kotlin/SKILL.md
- kafkaskills/kafka/SKILL.md
- klarsprakskills/klarsprak/SKILL.md
- ktor-scaffoldskills/ktor-scaffold/SKILL.md
- naisskills/nais/SKILL.md
- nav-architecture-reviewskills/nav-architecture-review/SKILL.md
- nav-authskills/nav-auth/SKILL.md
- nav-deep-interviewskills/nav-deep-interview/SKILL.md
- nav-dekoratorenskills/nav-dekoratoren/SKILL.md
- nav-planskills/nav-plan/SKILL.md
- nav-troubleshootskills/nav-troubleshoot/SKILL.md
- observability-debuggingskills/observability-debugging/SKILL.md
- observability-setupskills/observability-setup/SKILL.md
- playwright-testingskills/playwright-testing/SKILL.md
- postgresql-reviewskills/postgresql-review/SKILL.md
- readme-reviewskills/readme-review/SKILL.md
- rust-developmentskills/rust-development/SKILL.md
- security-owaspskills/security-owasp/SKILL.md
- security-reviewskills/security-review/SKILL.md
- spring-boot-scaffoldskills/spring-boot-scaffold/SKILL.md
- terse-modeskills/terse-mode/SKILL.md
- threat-modelskills/threat-model/SKILL.md
- tokenx-authskills/tokenx-auth/SKILL.md
- web-design-reviewerskills/web-design-reviewer/SKILL.md
- workstation-securityskills/workstation-security/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

