인프런 커뮤니티 질문&답변

주코딩님의 프로필 이미지
주코딩

작성한 질문수

안드로이드와 백엔드 협업시 타입 불일치에대해 질문합니다.

작성

·

108

0

안녕하세요. 저는 안드로이드 개발자로 백엔드와 협업을 하면서 겪게된 문제로 질문을 하려고합니다.

백엔드분이 명세해주신 Swagger를 보면 성공적으로 데이터를 받아 왔을때

 

{
  "code": 0,
  "message": "null",
  "content": [
    {
      "authorId": 0,
      "username": "string",
      "UserProfileImageUrl": "string",
      "currentJob": "회사원",
      "grade": "JUNIOR",
      "profileTitle": "프로필 제목",
      "introduceFirst": "자기소개 첫째줄",
      "introduceSecond": "자기소개 둘째줄",
      "introduceThird": "자기소개 셋째줄"
    }
  ]
}

이렇게 날라오는데 혹시나 어떠한 오류가 발생했을땐

{
  "code": 401,
  "message": "Failed JWT verification!",
  "content": "UNAUTHORIZED"
}

이렇게 에러코드와 메세지를 주면서 content에서도 어떤 문제가 생겼지, 문자열로 변환이 되어서 날라옵니다.

즉, content의 타입이 객체에서 문자열로 바뀌게 됩니다.

 

저의 코드는 이러합니다.

data class ResponseDto<T>(
    @SerializedName("code") val code: Int,
    @SerializedName("message") val message: String?,
    @SerializedName("content") val content: T?
)
data class AuthorResponseDto(
    @SerializedName("authorId") val authorId: Int,
    @SerializedName("userName") val userName: String,
    @SerializedName("userProfileImageUrl") val userProfileImageUrl: String,
    @SerializedName("currentJob") val currentJob: String,
    @SerializedName("grade") val grade: String,
    @SerializedName("profileFirst") val profileFirst: String,
    @SerializedName("profileSecond") val profileSecond: String,
    @SerializedName("profileThird") val profileThird: String
)
interface WriterApiService {
    @GET("api/v1/authors")
    @Headers("Authorization: Bearer ${Constants.USER_ACCESS_TOKEN}")
    suspend fun authors(
        @Query("lastAuthorId") lastAuthorId: Int,
        @Query("specialtyFilter") specialtyFilter: String
    ): ResponseDto<AuthorResponseDto>
}

 

현재 ResponseDto DataClass는 어떠한 API를 쓸때마다 계속 사용하고있어 제네릭타입으로 사용하고 있었습니다.

그러나 에러가 발생했을때 타입 불일치로 ( content는 에러 발생시 String으로만 값을 주고 있음 ) 백엔드에서 보내주는 에러 메세지와 에러 코드 자체를 볼 수 가없는 상황입니다 ㅠ

 

백엔드분께 이에대해 문제를 제기해보니, 이건 안드로이드 개발자인 제가 이 명세서에 맞게 분기처리를 해줘야 한다고합니다.

iOS 개발자님께 이 분기처리를 어떻게 해주었냐고 여쭈어 보았더니 이런 문제를 겪어 본적이 없어 해결방안을 얻지 못하였습니다..

 

하지만 약간의 의구심과 해결 방법을 알고싶습니다 ㅠ

 

  1. 백엔드와 협업할때 당연히 발생하는 문제인지?

  • 어차피 에러 코드와 메세지를 보내주는데 굳이 객체를 담고 있는 content를 에러메세지 형식으로 보내는것이 맞는지?

 

  1. 해당 문제를 어떻게 해결하면 좋을지..

  • 안드로이드에서 처리를 해야한다면 각 타입에 따라 분기 처리를 해줘야 하는지?

 

  1. 이건 제네릭 타입으로 하면 안되는건가..?

  • 분기 처리 문제가 아니라 애초에 제가 코드상으로 타입이라던지 반환값등을 잘못 설정 하고 있는건지

 

 

이 문제로 3일간 고민해보고 gpt, 린튼등 ChatBot과 레퍼런스등을 참고하고있는데 확실한 답을 찾기가 어렵습니다..

도움 요청합니다!!!!

 

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

주코딩님, 안드로이드와 백엔드 협업에서 타입 불일치 문제가 발생하는 상황에 대해 설명해 주셔서 감사합니다. 질문하신 사항들에 대해 차근차근 답변을 드리겠습니다.

  1. 백엔드와 협업할 때 당연히 발생하는 문제인지?
    네, 백엔드와 프론트엔드 간의 통신에서 특히 JSON 형태의 데이터를 주고받을 때, 데이터의 문제나 예외 상황을 처리하는 방식에서의 불일치가 종종 발생할 수 있습니다. 일반적으로는 이런 문제를 피하기 위해 미리 명확한 통신 규격을 정의하고 협의하는 것이 중요합니다.

  2. 해당 문제를 어떻게 해결하면 좋을지?

    • 안드로이드에서 처리를 해야 한다면, 여러 방법이 있겠지만 기본적으로는 통신 결과를 분기 처리하는 방식으로 해결할 수 있습니다. 즉, ResponseDtocontent를 파싱하기 전에 codemessage 값으로 성공인지 에러인지를 판별하여 적절한 처리를 하는 것이 필요합니다.
  3. 이건 제네릭 타입으로 하면 안 되는 건가?

    • 현재 작성하신 제네릭 타입도 가능하지만, 에러 처리 부분을 위해 좀 더 명확한 타입 체크와 분기 처리가 필요합니다. 아래는 예시 코드를 제공해드리겠습니다.
sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val code: Int, val message: String) : Result<Nothing>()
}

suspend fun fetchAuthors(apiService: WriterApiService, lastAuthorId: Int, specialtyFilter: String): Result<AuthorResponseDto> {
    return try {
        val response = apiService.authors(lastAuthorId, specialtyFilter)
        if (response.code == 0) {
            Result.Success(response.content!!)
        } else {
            Result.Error(response.code, response.message ?: "")
        }
    } catch (e: Exception) {
        Result.Error(-1, e.localizedMessage ?: "Unknown error")
    }
}

위 코드는 ResponseDto<AuthorResponseDto>를 받아오고, 그 결과를 Result.Success 또는 Result.Error로 변환하여 타입에 따른 분기 처리를 가능하게 합니다.

추가적으로, 아래 링크들을 통해 더 많은 정보를 얻을 수 있습니다:

백엔드와의 협업에서 발생하는 이러한 문제는 충분히 해결 가능한 부분이니, 너무 고민하지 마시고 차근차근 접근해 보시기 바랍니다. 도움이 필요하시다면 언제든 다시 질문해 주세요!

주코딩님의 프로필 이미지
주코딩

작성한 질문수

질문하기