[Android] Retrofit2 사용 시 response body가 비어있는 API 대응하기

akim·2023년 5월 20일
0
post-thumbnail

보통 REST API 의 응답 객체는

 {
        "status" : "success",
        "message" : null,
        "data" : { data1 }
    }

위와 같이 상태, 메세지, 데이터 형식으로 주어지는 것이 일반적이다.

따라서 파라미터 값에 따라 리스폰스 반환 값을 만드는 데 실패하게 되는 경우에도 어쨌거나 '실패'라는 응답을 받게 된다. 그러면 클라이언트 측에서는 해당 리스폰스에 따라 예외처리를 해주면 된다.


그러나!


여러 프로젝트를 진행하다보면 api 응답 형식이 각자 다른 것을 알 수 있다.
나의 경우 이번 프로젝트에서 파라미터 값에 따라 리스폰스가 아예 비어있는 경우가 존재하는 api를 다루게 되었다.

서버 개발자에게 실패의 경우에도 리스폰스를 만들어달라 할 수 있다면 그것이 베스트일테지만, 나는 클라이언트 측에서 response body가 null인 경우에 대응해보고자 노력해보았다.

그리고 혹시 또 나와 같은 상황에 처해있는 사람이 있을 수 있으니 과정과 결과를 공유해보고자 한다.


문제 상황

주어진 상황은 친구를 추가하는 화면에서

  1. 어떤 유저의 고유코드를 파라미터로 넘기면
  2. 그 고유코드에 해당하는 유저 정보를 response body로 반환해주는

api를 연동해야 하는 상황이다.


여기서 만약 고유 코드에 해당하는 유저가 없다면 리스폰스가 비어있어 아래와 같이 'Content-Length 가 0' 이라는 말과 함께 java.io.EOFExption 을 발생시키게 된다.


1차 해결: 컨버터 추가

java.io.EOFExption에 대한 에러코드를 구글링해보니 response body가 비어있는 경우 해당 응답을 null로 변환하는 Retrofit 컨버터를 추가해줄 수 있었다.

Retrofit Github Issue 중에 아래와 같이 컨버터에 대한 코드를 공유해준 유저가 있었고,

더 아래로 내려가다보면 Kotlin 개발자를 위해 Kotlin으로 해당 컨버터 코드를 올려준 사람도 있었다!!!!

그래서 당장 Retrofit 구현체에 이를 아래와 같이 적용시켜 주었는데, 여전히 같은 에러를 만날 수 있었다......

좌절할 뻔 하였으나.. 아래와 같이 nullOnEmptyConverterFactory 컨버터 를 GsonConverterFactory.create(gson) 컨버터보다 먼저 써줘야 하는 문제였다.

private val nullOnEmptyConverterFactory = object : Converter.Factory() {
    fun converterFactory() = this
    override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit) = object : Converter<ResponseBody, Any?> {
        val nextResponseBodyConverter = retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
        override fun convert(value: ResponseBody) = if (value.contentLength() == 0L) null else nextResponseBodyConverter.convert(value)
    }
}

2차 해결: Response body를 널러블하게 변경

그리고 이제 잘 되나 시도해보았더니...

이제는 다른 에러가 뜨기 시작했다.

response body가 non-null 타입으로 지정되어 있는데 null response가 들어왔다는 것이다. 보통은 response body가 null일 일이 없기 때문에 당연히 고려해보지 못한 부분이었다.


그래서 아래와 같이 인터페이스에서 리스폰스 값을 널러블하게 바꿔주었고

리스폰스의 유저 정보를 옵저빙할 때 널값인 경우 검색 결과가 없다는 텍스트를 띄울 수 있도록 아래와 같이 예외처리를 해주었다.


결과

이제 해당 고유코드를 가진 유저가 없는 경우에는 에러 없이 이렇게 잘 작동하는 것을 확인할 수 있다.


결론: nullOnEmptyConverterFactory 컨버터를 추가해주고 해당 리스폰스 바디를 널러블하게 바꿔주면 된다!

profile
학교 다니는 개발자

0개의 댓글