-
Notifications
You must be signed in to change notification settings - Fork 1
역 직렬화 라이브러리 비교
- 작성자 : 2taezeat
- 작성일자 : 23.11.14(화)
--
-
android application 에서는 주로
retrofit2
을 사용하여, json(JavaScript Object Notation) 을 주고 받으면서 서버와 통신한다. -
json 직렬화(Serialization) 란, 프로그래밍 언어에서 사용되는 데이터 구조를 json 형식으로 변환하는 과정
-
역직렬화 : 직렬화된 데이터를 다시 객체의 형태로 만드는 것
-
retrofit 를 이용하여 서버와 통신할 때, converter를 지정해주면 retrofit이 자동으로 역/직렬화 를 수행해준다.
-
이때, 여러 converter, 역/직렬화 라이브러리 들이 있다.
- 대표적으로
Gson
,Moshi
,kotlinx.serialization
이 존재한다.
- 대표적으로
-
3가지 라이브러리들을 비교 해보고
kotlinx.serialization
를 선택한 이유와 특징을 살펴본다.
- Google에서 개발한 Java 기반의 오픈 소스 json 데이터 처리 라이브러리
- Gson은 현재 maintenance mode로 새로운 기능을 개발하는 것이 아닌 bug fix와 같은 유지보수성 업데이트만 진행되고 있다.
- retrofit을 만든, Square사에서 개발한 json 직렬화 라이브러리로, java와 kotlin에서 JSON 데이터를 처리하는 데 사용된다.
-
높은 성능과 속도: Moshi는 경량화, 최적화된 구조를 통해 높은 성능을 지원한다.
-
Kotlin 호환성: Moshi는 Kotlin과의 높은 호환성을 가지고 있다. Kotlin의 Nullable 형식을 자동으로 처리하여, JSON 데이터를 다룰 수 있도록 지원한다.
-
정적 타입 지원: Moshi는 코드 생성(codegen)을 통해 정적 타입 어노테이션을 지원합니다. 이를 활용하여 JSON 데이터의 파싱 과정에서 타입 안정성을 제공하고, 컴파일 시간에 발생할 수 있는 오류를 미리 방지할 수 있다.
-
코드 자동 생성(codegen): Moshi는 어노테이션 기반 코드 생성을 지원하여 JSON 데이터 처리를 런타임이 아닌 컴파일 시점에 처리할 수 있게 해준다.
-
kotlin 1.4 version 에서 나온
JetBrain
이 개발한 역/직렬화 라이브러리 -
다른 컨버터 라이브러리와 다르게
Reflection
을 사용하지 않고 개발한 라이브러리 (성능 이점)
- kotlin의
default value
기능을 사용할 수 있다. - KMM, kotlin/js, kotlin/native 에서도 사용가능하다.
@Serializable
data class Project(
val name: String,
val language: String = "Kotlin"
)
이 문자열을 Gson 라이브러리로 파싱하면, name에는 정상적으로 값이 대입되지만 language 에는 null이 대입된다. 즉, non-null인 프로퍼티가 null 값을 가지게 될 뿐 아니라, language 프로퍼티의 기본값 조차 반영되지 않는 문제가 발생한다.
println(Gson().fromJson(inputString, Project::class.java))
//Gson: Project(name=kotlinx.serialization, language=null)
println(Json.decodeFromString<Project>(inputString))
//kotlinx.serialization: Project(name=kotlinx.serialization, language=Kotlin)
- 기본적으로
@Serializable
이 있는 클래스만 직렬화한다.- 직렬화를 수행할 수 없는 경우 런타임 에러 대신 컴파일 에러가 발생하므로 버그를 사전에 방지가 가능하다.
@Serializable
data class Project(
val name: String,
val owner: User, // 컴파일 에러 발생: Serializer for type User has not been found
val language: String = "Kotlin"
)
// @Serializable 어노테이션이 없으므로 직렬화를 지원하지 않습니다.
data class User(val userName: String)
이 떄, 직렬화를 지원하지 않는 클래스인 User 클래스를 직렬화를 지원하는 Project 클래스의 프로퍼티로 넣으면 다음과 같이 컴파일 에러가 발생한다.
- 상속 구조나 다형성을 파악해 직렬화를 해준다.
@Serializable
sealed class Project {
abstract val name: String
var status = "open"
}
@Serializable
@SerialName("owned")
class OwnedProject(override val name: String, val owner: String) : Project()
fun main() {
val json = Json { encodeDefaults = true } // "status" will be skipped otherwise
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
println(json.encodeToString(data))
}
// {"type":"owned","status":"open","name":"kotlinx.coroutines","owner":"kotlin"}
Moshi이 Gson에 비해 장점도 있지만, 서술한 kotlinx.serialization
의 대표적인 특징 때문에,
retrofit의 역/직렬화 converter 라이브러리는 kotlinx.serialization
으로 선택하였다.
- 프로젝트 생성
- 프로젝트 구조
- PR에 대한 단위 테스트 자동화
- 역/직렬화 라이브러리 비교
- Github Release 자동화
- Firebase App 배포 자동화
- 플러그인을 이용하여 공통 설정 없애기
- Timber 라이브러리를 사용한 이유
- 네트워크 예외 처리
- Kotest 도입기