ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Moshi vs KotlinX Serialization
    Android 2025. 7. 12. 00:05

    안드로이드 개발에서 JSON 직렬화/역직렬화 라이브러리 선택 어떻게 하고 계시나요?

    JSON 데이터를 앱에서 사용할 수 있는 객체로 변환하는 것이 직렬화,
    반대로 객체를 JSON으로 변환하는 과정이 역직렬화입니다

    과거 Gson이 널리 사용되었지만, 코틀린의 null-safety를 제대로 지원하지 않고 default value를 무시하는 등의 문제로 인해

    현재는 Moshi와 KotlinX Serialization이 양강 구도를 형성하고 있습니다


    이번 글에서는 두 라이브러리의 특징을 심도 있게 비교하고, 어떤 상황에서 어떤 라이브러리를 선택해야 하는지 살펴보겠습니다.

    라이브러리 버전 및 업데이트 동향

      Moshi KotlinX Serialization
    최신 버전 1.15.2 1.9.0
    마지막 업데이트 2024년 12월 5일 2025년 6월 27일
    활발도 매우 활발 매우 활발
    설계 철학 Java 기반에 Kotlin 지원 추가 Kotlin 전용으로 설계


    두 라이브러리 모두 2025년에도 매우 활발하게 업데이트되고 있습니다

    Moshi는 Square에서 지속적으로 관리하고 있고
    KotlinX Serialization은 JetBrains의 공식 지원을 받아 Kotlin 2.2.0까지 지원하고 있습니다

     

    2025년 6월 말 1.9.0 릴리즈

     



    2025년 벤치마크 결과

    핵심 벤치마크 결과

    소규모 JSON 처리

    • KotlinX Serialization이 직렬화(객체 → JSON)에서 약 2배 빠름
    • Moshi가 역직렬화(JSON → 객체)에서 더 나은 성능

    대용량 JSON 처리

    • Moshi가 역직렬화에서 최대 2배 빠름
    • 메모리 할당: KotlinX가 3배 많은 객체를 메모리에 할당



    네트워크 통신에서의 실제 성능


    Moshi는 Retrofit과의 통합에서 강점을 보이고

    Okio와의 결합으로 버퍼 공유가 가능해 네트워크 레이어에서 효율적입니다

    // Retrofit + Moshi
    val retrofit = Retrofit.Builder()
        .baseUrl("<https://api.example.com/>")
        .addConverterFactory(MoshiConverterFactory.create())
        .build()
    
    // Retrofit + KotlinX Serialization (별도 컨버터 필요)
    val retrofit = Retrofit.Builder()
        .baseUrl("<https://api.example.com/>")
        .addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
        .build()

     

     

    Kotlin 친화성 및 기능 지원 비교

     

      Moshi KotlinX Serialization
    개발사 Square (Retrofit, OkHttp 개발사) JetBrains (Kotlin 개발사)
    설계 철학 Java 기반에 Kotlin 지원 추가 Kotlin 전용으로 설계
    리플렉션 사용 런타임 리플렉션 사용 컴파일 타임 코드 생성
    필수 어노테이션 @JsonClass(generateAdapter = true) @Serializable
    오류 검출 런타임 오류 컴파일 타임 오류
    Java 호환성 완전 지원 제한적

     

     

    1. Sealed Class 지원

    KotlinX Serialization의 압도적 우위

    @Serializable
    sealed class Result<out T> {
        @Serializable
        data class Success<T>(val data: T) : Result<T>()
        
        @Serializable
        data class Error(val message: String) : Result<Nothing>()
    }
    
    // 간단한 직렬화/역직렬화
    val json = Json.encodeToString(result)
    val parsed = Json.decodeFromString<Result<String>>(json)

     

    Moshi의 복잡한 설정

    val moshi = Moshi.Builder()
        .add(PolymorphicJsonAdapterFactory.of(Result::class.java, "type")
            .withSubtype(Result.Success::class.java, "success")
            .withSubtype(Result.Error::class.java, "error"))
        .build()
    

     

    2. Object 지원

    KotlinX Serialization

    @Serializable
    object AppConfig {
        val version = "1.0.0"
        val apiUrl = "<https://api.example.com>"
    }
    
    val json = Json.encodeToString(AppConfig) // 간단한 직렬화
    

    Moshi object 타입은 기본 지원하지 않아서 별도 어댑터 작성 필요

    → 팀 프젝에서 KotlinX Serialization를 채택하게 된 이유

    navigation에서 object를 간단히 직렬화하기 위해 
    KotlinX Serialization 선택

     

     

    3. Default Value 처리

    KotlinX Serialization

    @Serializable
    data class User(
        val name: String,
        val age: Int = 25, // 기본값 적용됨 (encodeDefaults = true 설정 시)
        val email: String? = null
    )

     

    Moshi

    @JsonClass(generateAdapter = true)
    data class User(
        val name: String,
        val age: Int = 25, // 코드생성 사용 시만 기본값 적용
        val email: String?
    )

     

     

    실무적 고려사항

    1. 기존 프로젝트 호환성

    • Moshi: Java와 Kotlin 혼합 환경에서 유리
    • KotlinX Serialization: Kotlin 전용 프로젝트에 최적화

    2. 생태계 지원

    • Moshi: Retrofit, OkHttp와 완벽한 통합
    • KotlinX Serialization: Ktor, Kotlin 멀티플랫폼에서 공식 지원

    3. 오류 처리 및 타입 안전성

    • KotlinX Serialization: 컴파일 타임에 오류 검출 가능
    • Moshi: 런타임 오류 가능성, 하지만 codegen 사용 시 안정성 향상

    4. 학습 곡선

    • Moshi: 기존 Java 개발자들에게 친숙
    • KotlinX Serialization: Kotlin 개발자들에게 직관적

     

    KotlinX Serialization 채택

    순수 Kotlin 프로젝트

    Sealed class, object 사용

    컴파일 타임 안전성 고려

    소규모~중규모 JSON 데이터 처리

    Kotlin 멀티플랫폼 개발

    *// KotlinX Serialization*
    @Serializable
    sealed class NavigationDestination {
        @Serializable
        object Home : NavigationDestination()
        
        @Serializable
        data class Profile(val userId: String) : NavigationDestination()
    }
    

     

    Moshi 채택

    대용량 JSON 데이터 처리

    Retrofit 중심의 네트워크 통신

    Java와 Kotlin 혼합 환경

    메모리 사용량이 민감한 환경

    복잡한 JSON 변환 로직이 필요한 상황

    // 복잡한 JSON 변환이 필요하다면 Moshi
    @JsonClass(generateAdapter = true)
    data class ComplexResponse(
        @Json(name = "user_data") val userData: UserData,
        @Json(name = "meta_info") val metaInfo: MetaInfo
    )

     


    절대적인 우위는 없고 프로젝트의 특성 요구사항에 따라 선택이 달라져야 한다는 것이 중요하다고 생각했습니다
    한쪽의 장점만 보고 결정하지 않고, 실제 벤치마크 데이터와 프로젝트 요구사항을 종합적으로 고려하는 것이 어느 라이브러리 선택에서나 중요하지 않을까 하는 결론을 짓고 글을 마치겠습니다 




    참고 자료

    1. https://github.com/square/moshi
    2. https://github.com/Kotlin/kotlinx.serialization/issues/2657
    3. https://github.com/Kotlin/kotlinx.serialization

Designed by Tistory.