Kotlinx-Serialization 를 통해 kotlinx-datetime type을 직렬화/역직렬화 하는 방법

이지훈·2023년 4월 21일
0

최근 gson 으로 직렬화/역직렬화를 수행하였던 프로젝트를 kotlinx-serialization 로 migration하는 리팩토링을 수행하였다

잘쓰던 gson 을 냅두고 kotlinx-serialization을 왜 사용하게 되었는지에 대해선 이미 좋은 글이 있기에 해당 글의 링크를 첨부하는 것으로 설명을 대체하도록 하겠다.

신입 안드로이드 개발자의 kotlinx-serialization-리팩토링 서사시

순조롭게 리팩토링을 진행하던 중, 아래와 같은 data class에서 문제를 직면하게 되었다.

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.Date

@Serializable
data class KakaoImageSearchDocument(
    @SerialName("collection")
    val collection: String,
    @SerialName("datetime")
    val datetime: Date, // <- 문제 발생 지점 
    @SerialName("display_sitename")
    val siteName: String,
    @SerialName("doc_url")
    val url: String,
    @SerialName("height")
    val height: Int,
    @SerialName("image_url")
    val imageUrl: String,
    @SerialName("thumbnail_url")
    val thumbnailUrl: String,
    @SerialName("width")
    val width: Int
)

Serializer has not been found for type 'Date'. To use context serializer as fallback, explicitly annotate type or property with @Contextual

Date type 을 직렬화할 수 없다는 의미의 에러였고, 커스텀 직렬화 클래스를 만들어서 직렬화를 수행하거나, @Contextual annotation을 붙히는 등의 해결책들을 찾을 수 있었다.

하지만 Date type 자체가 Java의 것이고 날짜, 시간등의 정보를 가져올 수 있는 레거시 라이브러리 이기에 이를 kotlin의 Instant 으로 변경해보기로 하였다.

코틀린의 라이브러리니까 지원을 해줄 것이라 생각했지만, 다음과 같은 에러를 뱉었다.

Serializer has not been found for type '[Error type: Unresolved type for Instant]'. To use context serializer as fallback, explicitly annotate type or property with @Contextual

kotlinx-Serialization 은 비교적 간단한 타입들의 대한 직렬화, 역직렬화를 제공해주고, Java의 Date, Kotlin의 LocalDate, LocalDateTime, Instant 와 같은 primitive가 아닌 타입에 대해선 제공을 해주지 않았다..

이에 대한 해결법을 찾기위해, 구글링 및 위에 신입 안드로이드 개발자의 kotlinx-serialization-리팩토링 서사시 글을 참고한 결과

kotlinx-datetime 라이브러리를 직렬화를 수행해야하는 모듈의 build.gradle 에 추가하면 성공적으로 직렬화를 수행할 수 있다는 글을 확인할 수 있었고, 라이브러리를 추가, import 하여 에러를 없앨 수 있었다.

package com.kenshi.data.model.image

import kotlinx.datetime.LocalDate
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

// 기존의 자바의 Date 를, kotlin Serialization 적용을 위해 kotlin 의 LocalDate 로 변경
// kotlinx-datetime 라이브러리 적용
@Serializable
data class KakaoImageSearchDocument(
    @SerialName("collection")
    val collection: String,
    @SerialName("datetime")
    val datetime: Instant,
    @SerialName("display_sitename")
    val siteName: String,
    @SerialName("doc_url")
    val url: String,
    @SerialName("height")
    val height: Int,
    @SerialName("image_url")
    val imageUrl: String,
    @SerialName("thumbnail_url")
    val thumbnailUrl: String,
    @SerialName("width")
    val width: Int
)

Java 의 Date 클래스와 호환되는 클래스는 kotlinx-datetime 의 Instant 이기 때문에 Instant 로 변경해주었고, 정상적으로 response 를 받아올 수 있었다.

참고 자료)
https://blog.mathpresso.com/신입-안드로이드-개발자의-kotlinx-serialization-리팩토링-서사시-740597911e2e

https://github.com/Kotlin/kotlinx.serialization#dependency-on-the-json-library

https://github.com/Kotlin/kotlinx-datetime#using-in-your-projects

https://m.blog.naver.com/PostView.naver?blogId=jetbrains_korea&logNo=222367947596&categoryNo=8&proxyReferer=

https://blog.jetbrains.com/kotlin/2021/05/kotlinx-datetime-0-2-0-is-out/

profile
실력은 고통의 총합이다. Android Developer

0개의 댓글