반응형

 

이전 글에서 Kotlinx.Serialization을 알아봤습니다.

[Kotlin/Library] - Kotlinx Serialization - 코틀린에 가장 적합한 Json Converter

 

Kotlinx Serialization - 코틀린에 가장 적합한 Json Converter

아마 REST API를 구현해보신 분이라면 JSON 데이터를 다뤄보신 경험이 있으실 겁니다. 개발을 하다보면 JSON 이나 XML 등을 다뤄야하는 경우가 자주 발생하는데요. 기본적으로 JSON 이나 XML 은 JVM 언어에 정의되..

readystory.tistory.com

아마 코틀린 언어를 가장 많이 사용하는 분야는 안드로이드일 것이라 생각하는데요.

직렬화 라이브러리는 단독으로 사용되기 보다는 Retrofit 등의 라이브러리와 함께 사용하여 JSON 데이터를 주고 받는 형태에 쓰이는 경우가 많습니다.

 

따라서 kotlin serialization 과 Retrofit 을 함께 사용하는 방법에 대해 실습해보도록 하겠습니다.

참고로 레트로핏 사용법에 대해서는 기본적으로 안다는 가정하에, 자세하게 설명하지 않습니다.

 

사전 작업

build.gradle 에 Serialization, Retrofit 에 대한 디펜던시를 추가해줍니다.

dependencies {
    // kotlin serialization
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0" // JVM dependency

    // retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.7.2'
    implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.5.0")
}

마지막 줄에 있는 converter가 바로 레트로핏과 kotlin serialization 을 연동시켜 주는 모듈입니다.

 

예제 코드

실습에 앞서 JSON 데이터를 요청하면 응답해주는 서버가 필요하겠죠?

이번 실습에서는 제가 자주 애용하는 fake server인 JSONPlaceholder 를 통해 실습해보도록 하겠습니다.

 

https://jsonplaceholder.typicode.com/albums/{id}로 요청하게 되면 다음과 같은 형태의 JSON 데이터를 응답해줍니다.

// https://jsonplaceholder.typicode.com/albums/3

{
  "userId": 1,
  "id": 3,
  "title": "omnis laborum odio"
}

 

따라서 우리는 이에 맞게 코틀린 data class를 작성해줍니다.

@Serializable
data class Album (
    val userId: Int,
    val id: Int,
    val title: String,
    val comment: String = "default comment"
)

 

앞서 보여드렸던 Json 데이터와는 달리, 코틀린에서 정의한 Album 클래스에는 commnet 라는 값이 있는 것도 보이실겁니다. 이는 Kotlin Serialization의 장점인 default value 도 정상적으로 사용 가능한가 테스트하기 위해서 추가해주었습니다.

 

다음으로 레트로핏에 사용될 인터페이스를 정의하겠습니다.

interface ReadyService {

    @GET("albums/{id}")
    fun getAlbum(@Path("id") id: Int): Call<Album>
}

 

그리고 레트로핏 객체를 선언해줍니다.

    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl("https://jsonplaceholder.typicode.com/")
        .addConverterFactory(Json.asConverterFactory(MediaType.parse("application/json")!!))
        .build()

 

Json.asConverterFactory() 함수는 Json 클래스에 정의된 함수가 아니라, 코틀린 익스텐션 함수를 통해 구현된 함수입니다.

 

자, 이제 모든 준비가 되었으니 통신을 해보도록 하겠습니다.

fun main() {
    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl("https://jsonplaceholder.typicode.com/")
        .addConverterFactory(Json.asConverterFactory(MediaType.parse("application/json")!!))
        .build()

    val service = retrofit.create(ReadyService::class.java)

    val call = service.getAlbum(3)
    val response = call.execute()

    if (response.isSuccessful) {
        val album: Album? = response.body()
        println(album)
    } else {
        println("Failed to load data.")
    }
}
Album(userId=1, id=3, title=omnis laborum odio, comment=default comment)

 

실행해보시면 id가 3인 Album 객체가 정상적으로 출력될 것입니다.

그리고 응답 값에는 없던 comment 필드에도 디폴트 값으로 설정해준 "default comment" 값이 제대로 들어가있을 것입니다.

 


위 예제 코드는 Github 저장소에서 확인할 수 있습니다.

반응형
반응형