본문 바로가기

안드로이드/트러블 슈팅

[안드로이드 트러블 슈팅] 서버 데이터 매핑 시, @SerializedName 어노테이션의 중요성


안녕하세요. 안드로이드 개발을 하다 보면 외부 API와의 통신은 필수적인 부분입니다. 이번 포스팅에서는 안드로이드 앱을 개발할 때, Retrofit을 사용하여 데이터를 받아오는 과정에서 JSON 형태의 서버 데이터를 data class를 이용해서 매핑 시, @SerializedName 어노테이션의 중요성에 대해 깨달은 트러블 슈팅 사례를 공유하고자 합니다.

1. 문제 상황

프로젝트를 3~4개월 정도 진행했을 때, 서버 통신 API가 약 30개 추가됐었습니다. 그에 맞춰서 서버 데이터를 매핑하는 DTO 클래스도 많이 생성돼 있었고, API 명세를 보면서 서버에서 반환하는 JSON 필드 이름과 안드로이드의 데이터 클래스 필드 이름을 동일하게 맞추어 개발했었습니다. @SerializedName 어노테이션을 사용하지 않았습니다.

예를 들어, 서버에서 반환하는 JSON 응답이 아래와 같다고 가정하겠습니다.

{
    "userName": "John Doe",
    "userAge": 30
}


이에 해당하는 DTO 클래스를 코틀린의 data class로 다음과 같이 작성했습니다.

data class User(
    val userName: String,
    val userAge: Int
)


이런 형태로 상당히 많은 양의 데이터 클래스가 생성돼 있었고, UI 영역에서는 해당 클래스의 필드를 직접 접근하는 형태로 개발이 돼있었습니다.

2. 발생한 문제

프로젝트 중반에 서버의 JSON 응답 형식이 변경되었습니다. 서버 팀은 리팩토링 차원에서 필드명을 변경하고, 이를 저에게 전달했습니다. 예를 들어, userName 필드가 name으로 변경되고 userAge 필드가 age로 변경된 것입니다. 그래서 앱 내부에서도 많은 부분을 수정해야 하는 상황이 되었고, 특히 UI 영역에서 직접 필드에 접근했던 코드들이 모두 에러가 발생했습니다.

3. 해결 방법

이 문제를 해결하기 위해서 @SerializedName 어노테이션을 사용했습니다. @SerializedName 어노테이션을 사용하면 서버의 JSON 필드명과 안드로이드 데이터 클래스의 필드명을 다르게 설정할 수 있어서, 서버에서 필드명을 변경해도 안드로이드 앱 코드는 큰 수정 없이 대응할 수 있었습니다.

변경된 서버 응답에 대응하는 데이터 클래스는 다음과 같이 수정되었습니다.

data class User(
    @SerializedName("name")
    val userName: String,

    @SerializedName("age")
    val userAge: Int
)


이러한 기능 덕분에 서버에서 필드명이 수정되어도 @SerializedName의 속성만 수정하면 되었고, UI 영역은 영향을 받지 않게 되었습니다. 즉, 서버의 JSON 응답 필드명이 변경되어도 Data 영역만 수정하면 됩니다. 

4. 안드로이드 @SerializedName 트러블 슈팅 정리

안드로이드에서 Retrofit을 사용하고, JSON 형태의 응답 데이터를 받기 위해 데이터 매핑 시, @SerializedName 어노테이션의 중요성에 대해 다시 한번 깨달았습니다. 특히 서버 측에서의 필드명이 확정되지 않은 초기 개발 단계에서는 이러한 방법을 적극 활용하는 것이 좋다고 생각합니다. @SerializedName 어노테이션을 통해 서버 데이터 매핑 변경사항에 더욱 유연하게 대응하고, 불필요한 개발 리소스 낭비를 줄일 수 있기 때문입니다.