Работа с YAML в Kotlin: библиотеки, примеры и парсинг

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с YAML в Kotlin: библиотеки, парсинг и сериализация

YAML (YAML Ain't Markup Language) — это популярный формат сериализации данных, который широко используется для конфигурационных файлов, описания зависимостей и обмена данными. Благодаря своей читаемости и лаконичности, YAML часто предпочитают JSON или XML. В экосистеме Kotlin существует несколько зрелых библиотек для работы с YAML. В этой статье мы рассмотрим три основных подхода: SnakeYAML, Kaml и Jackson YAML.

1. SnakeYAML — классический выбор

SnakeYAML — это самая популярная Java-библиотека для парсинга YAML, которая отлично работает и в Kotlin. Она предоставляет низкоуровневый API, позволяющий читать YAML как Map, List или произвольные объекты.

Подключение (Gradle)

dependencies {
    implementation("org.yaml:snakeyaml:2.2")
}

Пример: чтение простого YAML

import org.yaml.snakeyaml.Yaml

fun main() {
    val yamlString = """
        server:
          host: "localhost"
          port: 8080
          ssl: false
        database:
          url: "jdbc:postgresql://localhost/mydb"
          user: "admin"
          password: "secret"
    """.trimIndent()

    val yaml = Yaml()
    val data: Map<String, Any> = yaml.load(yamlString)
    println(data)
    // Вывод: {server={host=localhost, port=8080, ssl=false}, database={url=jdbc:postgresql://localhost/mydb, user=admin, password=secret}}
}

Пример: маппинг в data class

import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor

data class ServerConfig(
    val host: String,
    val port: Int,
    val ssl: Boolean
)

data class DatabaseConfig(
    val url: String,
    val user: String,
    val password: String
)

data class AppConfig(
    val server: ServerConfig,
    val database: DatabaseConfig
)

fun main() {
    val yamlString = """
        server:
          host: "localhost"
          port: 8080
          ssl: false
        database:
          url: "jdbc:postgresql://localhost/mydb"
          user: "admin"
          password: "secret"
    """.trimIndent()

    val yaml = Yaml(Constructor(AppConfig::class.java))
    val config: AppConfig = yaml.load(yamlString)
    println(config.server.host) // localhost
    println(config.database.port) // Ошибка! port нет в DatabaseConfig
}

Важно: SnakeYAML использует рефлексию Java, поэтому data class должны иметь конструктор без параметров или использовать Constructor с указанием класса. Для вложенных структур может потребоваться ручное конфигурирование.

2. Kaml — нативная Kotlin-библиотека

Kaml (Kotlin YAML library) — это современная библиотека, написанная на Kotlin с использованием kotlinx.serialization. Она обеспечивает типобезопасность, поддержку sealed class, nullable-полей и кастомных сериализаторов.

Подключение (Gradle)

dependencies {
    implementation("net.mamoe.yamlkt:yamlkt:0.13.0")
    // или
    implementation("com.charleskorn.kaml:kaml:0.56.0")
}

Рассмотрим Kaml от charleskorn, так как он более популярен и активно развивается.

Пример: сериализация и десериализация

import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import com.charleskorn.kaml.Yaml

@Serializable
data class ServerConfig(
    val host: String = "localhost",
    val port: Int = 8080,
    val ssl: Boolean = false
)

@Serializable
data class AppConfig(
    val server: ServerConfig,
    val name: String
)

fun main() {
    val config = AppConfig(
        server = ServerConfig(host = "example.com", port = 443, ssl = true),
        name = "MyApp"
    )

    // Сериализация в YAML
    val yamlOutput: String = Yaml.default.encodeToString(config)
    println(yamlOutput)
    // Вывод:
    // server:
    //   host: example.com
    //   port: 443
    //   ssl: true
    // name: MyApp

    // Десериализация из YAML
    val yamlInput = """
        server:
          host: test.local
          port: 9000
        name: TestApp
    """.trimIndent()

    val parsedConfig: AppConfig = Yaml.default.decodeFromString(yamlInput)
    println(parsedConfig.server.host) // test.local
}

Преимущества Kaml

  • Типобезопасность — все проверяется на этапе компиляции
  • Поддержка null и default values —

Рекомендаций