프레임워크(Framework)/Ktor

[Ktor] Kotlin 객체로 Yml 파일 읽어서 사용하기 - Jackson 라이브러리 활용

잇트루 2023. 7. 17. 20:45
반응형

Intro

Spring Boot에서는 @Value 어노테이션을 통해 yml, properties 등 파일의 구성 정보를 쉽게 읽어서 값을 가져올 수 있다.

반면에 Ktor 프레임워크에서는 Kotlin 코드, HOCON(.conf), YAML(.yaml 또는 .yml) 파일을 통해 다양한 서버 환경 변수를 구성할 수 있다. yml(yaml) 파일을 통해 설정한 정보들을 관리할 경우에는 여러 라이브러리(Jackson, snakeyaml 등)를 활용하여 yml 파일을 직접 읽어서 변환한 후 사용해야 한다.

Spring Boot 환경과 유사하게 YML 파일로 서버 환경 변수를 구성하고, Jackson 라이브러리를 활용해서 YML 파일을 객체로 매핑하여 프로퍼티 값으로 사용해 보고자 한다.

 

 

build.gradle.kts

다음과 같이 Jackson 라이브러리의 필요한 의존성을 추가한다.

dependencies {
    ...

    implementation("com.fasterxml.jackson.core:jackson-databind:2.14.2")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.2")

    ...
}

com.fasterxml.jackson.core:jackson-databind

데이터 바인딩 기능을 제공한다. ObjectMapper 클래스와 같은 핵심 기능을 포함하고 있으며 YML 파일을 읽어 객체로 변환하기 위해 사용한다.

 

com.fasterxml.jackson.module:jackson-module-kotlin

Jackson 라이브러리와 Kotlin 언어 간의 통합을 위한 모듈을 제공한다. Jackson 라이브러리를 Ktolin 프로젝트에서 편리하게 사용할 수 있도록 한다. null 안전성 지원, Kotlin 객체를 직렬화 및 역직렬화하는 데 사용한다.

 

com.fasterxml.jackson.dataformat:jackson-dataformat-yaml

YML 형식의 데이터를 처리하기 위한 데이터 포맷 모듈을 제공한다. YML 파일을 읽고 쓰는 등의 기능을 사용할 수 있으며, YAMLFactory 클래스를 통해 YML 데이터를 처리할 수 있다.

 

 

YML

Spring boot와 마찬가지로 Ktor 프레임워크에서 데이터베이스와 연결하기 위해서는 Url, Driver, Username, Password 등의 정보가 필요하다.

application.yml

ktor:
    application:
        modules:
            - com.example.ApplicationKt.module
    deployment:
        port: 8080

ktorm:
    database:
        url: "jdbc:mysql://localhost:3306/ktorm"
        driver: "com.mysql.cj.jdbc.Driver"
        username: "root"
        password: "admin"

ktor

application.modules와 deployment.port는 Ktor 애플리케이션에서 사용할 모듈들과 바인딩될 포트 번호를 나타낸다.

ktorm

코틀린 기반의 ORM 라이브러리인 ktorm을 사용하여 데이터베이스 설정을 구성한 내용이다. mysql에 연동할 url과 JDBC 드라이버, 사용자 이름과 비밀번호를 구성하고 있다.

 

 

YML to Object

위에서 구성한 application.yml 파일을 읽기 위해 구조를 정의해야 한다.

ApplicationConfig.kt

data class YamlConfig(
    val ktor: KtorConfig,
    val ktorm: KtormConfig
)

data class KtorConfig(
    val application: ApplicationConfig,
    val deployment: DeploymentConfig
)

data class ApplicationConfig(
    val modules: List<String>
)

data class DeploymentConfig(
    val port: Int
)

data class KtormConfig(
    val database: DatabaseConfig
)

data class DatabaseConfig(
    val url: String,
    val driver: String,
    val username: String,
    val password: String
)

fun loadYamlConfig(): YamlConfig {
    val objectMapper = ObjectMapper(YAMLFactory()).registerModule(KotlinModule())
    val yamlFile = File("src/main/resources/application.yaml")
    return objectMapper.readValue(yamlFile, YamlConfig::class.java)
}

val yamlConfig = loadYamlConfig()

YamlConfig

  • yml 파일의 구조를 정의하는 데이터 클래스로 KtorConfig와 KtormConfig 객체를 포함한다.
  • yml 파일의 전체 내용을 가지게 된다.

 

KtorConfig

  • yml 파일의 ktor에 해당하는 하위 내용을 가진 데이터 클래스로 ktor.application에 해당하는 ApplicaionConfig 객체와 ktor.deployment에 해당하는 DeploymentConfig 객체를 가진다.
  • 이후 마찬가지로 ApplicaionConfig와 DeploymentConfig를 데이터 클래스로 정의해 주어야 한다.
  • ApplicaionConfig의 프로퍼티는 String 형태의 List를 가지며 yml 파일의 ktor.application.modules에 해당한다.
  • DeploymentConfig의 프로퍼티는 Int를 가지며 yml 파일의 ktor.deployment.port에 해당한다.

 

KtormConfig

  • yml 파일의 ktorm에 해당하는 하위 내용을 가진 데이터 클래스로 ktorm.database에 해당하는 DatabaseConfig 객체를 가진다.
  • DabaseConfig는 YML에 정의한 데이터베이스 연동을 위한 구성 정보(jdbcurl, driver, username, password)를 가진다.

 

loadYamlConfig()

  • loadYamlConfig 함수는 YML 파일의 구성 정보를 읽어 객체로 반환하는 함수다.
  • ObjectMapper를 통해 매핑할 객체를 생성한다. YAMLFactory를 사용하여 YML 형식의 데이터를 처리할 수 있도록 설정하고, KotlinModule을 등록하여 Kotlin 클래스와의 직렬화 및 역직렬화를 지원한다.
  • 다음 실제로 구성한 yml 파일의 경로를 통해 File 객체를 생성한다.
  • ObjectMapper에서 지원하는 readValue() 메서드를 통해 생성한 yml 파일을 읽고, 위에서 정의한 YamlConfig 클래스로 변환한다.

 

 

프로퍼티 접근하기

이제 loadYamlConfig 함수를 통해 생성한 yamlConfig를 통해 yml 파일의 내용을 변환한 YamlConfig 객체를 얻을 수 있게 된다.

fun main() {
    val applicationModules = yamlConfig.ktor.application.modules
    val deploymentPort = yamlConfig.ktor.deployment.port

    println("applicationModules = ${applicationModules}")
    println("deploymentPort = ${deploymentPort}")

    println()
    
    val jdbcUrl = yamlConfig.ktorm.database.url
    val jdbcDriver = yamlConfig.ktorm.database.driver
    val username = yamlConfig.ktorm.database.username
    val password = yamlConfig.ktorm.database.password

    println("jdbcUrl = ${jdbcUrl}")
    println("jdbcDriver = ${jdbcDriver}")
    println("username = ${username}")
    println("password = ${password}")
}
// 실행 결과
applicationModules = [com.example.ApplicationKt.module]
deploymentPort = 8080

jdbcUrl = jdbc:mysql://localhost:3306/ktorm
jdbcDriver = com.mysql.cj.jdbc.Driver
username = root
password = admin

 

따라서 Ktorm을 사용하여 데이터베이스를 연동하기 위해 다음과 같이 설정할 수 있게 된다.

object DatabaseConnection {

    val database = Database.connect(
        dataSource = HikariDataSource(
            HikariConfig().apply {
                jdbcUrl = yamlConfig.ktorm.database.url
                driverClassName = yamlConfig.ktorm.database.driver
                username = yamlConfig.ktorm.database.username
                password = yamlConfig.ktorm.database.password
            }
        ),
        dialect = MySqlDialect(),
        logger = ConsoleLogger(threshold = LogLevel.INFO),
        alwaysQuoteIdentifiers = true,
        generateSqlInUpperCase = false
    )
}
반응형