[Android] Retrofit으로 Json 불러오기

0

개발을 하다보면 아래의 상황에서 Local Json File을 사용하게 됩니다.

  • 과제 테스트를 할때
  • Local Test를 할때
  • API 정의만 되어있고, 아직 완성이 안되었을때

일반적으로 Android 프로젝트는 Retrofit이라는 통신 라이브러리를 사용합니다.
Retrofit을 이용하게 되면, Gson처럼 자동으로 파싱을 하기때문에 편리하나, 로컬 json 파일을 읽는 기능은 따로 존재하지 않습니다.

물론 Local에서 Test를 할경우 mockWebServer Library를 이용하여 통신을 조작하긴 합니다만, 테스트 용도에서 사용하라고 권장하고 있습니다.

그래서 단순히 파일을 read하고 Gson으로 파싱하자니, 테스트하기위한 불필요한 코드가 추가되어서 불편합니다.

어떻게 Retrofit으로 Json 파일을 읽을수 있을까요?

답은 Interceptor에 있습니다.

1.Interceptor란?

Retrofit은 내부적으로 OkHttp 통신 라이브러리를 사용합니다.
Application에서 Request를 던져주면 Okhttp으로 통신하고 결과값을 가져옵니다.

이때 우리는 Application에 돌아오는 값을 Interceptor를 통해 조작할 수 있습니다.

Interceptor는 과연 어떤일까지 가능할까요?

  1. 공통 헤더
    일반적으로 Interceptor는 공통 헤더를 장착할때 많이 사용됩니다.
val newRequest = chain.request().newBuilder()
    .addHeader("token", NaverToken).build()

예를 들어, 어떤페이지로 접근하려면 토큰을 헤더에 붙여야하는데 Interceptor를 이용하여, 쉽게 대응이 가능하죠.

  1. 서버로 부터 응답 받기
    chain.proceed를 이용하여 서버로 통신 값을 받아올수 있습니다.
    값 변형또한 가능하죠.
    proceed를 사용하지 않았다면 네트워크를 통신하지 않습니다.
val response = chain.proceed(newRequest)

감이 좀 오셨나요? Interceptor로 request를 가로챈뒤 proceed를 사용하지않으면 해결되는 문제입니다!

2. 코드를 짜보자

방향을 잡았으면 코드짜야겠죠.

런타임때 json 파일을 불러와야하기때문에 Asset폴더에 파일을 넣어둡시다.
왜 그런지 이유는 Android-Asset-vs-Row-vs-Resource에서 참고하세요.

class MockRequestInterceptor(private val context: Context) : Interceptor {

    companion object {
        private val JSON_MEDIA_TYPE = "application/json".toMediaTypeOrNull()
        private const val MOCK = "mock"
    }


override fun intercept(chain: Interceptor.Chain): Response {
	val filename = request.url.pathSegments.last()
	return Response.Builder()
    	.request(request)
    	.protocol(Protocol.HTTP_1_1)
    	.message("")
    	.code(200)
    	.body(context.readFileFromAssets("api-response/$filename.json").toResponseBody(JSON_MEDIA_TYPE))
    	.build()

통신이 발생하면 Interceptor가 Application 통신을 가로채게됩니다.
proceed()가 발생하지 않았기 때문에 실제로 네트워크 통신은 일어나지 않았고,
Response를 따로 생성하여 Json값을 Body로 넣었습니다.

해당 로직을 통해 API의 EndPoint들이 네트워크가 아닌 로컬에서 발생 됩니다!

3. 조금더 깊이 가보자! 언제 Gson Converter가 발생될까?

Retrofit의 데이터 흐름을 가져와봤습니다.

나머지는 자세히 볼필요 없고 아래에 색깔을 칠한것을 보시면됩니다.

Converter와 OKHttp가
RequestBody와 ResponseBody를 통해 직접 전달
되는것을 확인할 수 있습니다.
(이 사진에서는 MoshiConverter라고 적혀있지만, GsonConverter가 될수도, Scala가 될수도 있습니다.)

그렇다면 Interceptor는 어디에 위치하게 될까요?

Interceptor는 이쪽부근에 위치하여, 통신을 가로챌수 있으며, ResponseBody를 조작할 수 있습니다.

읽어주셔서 감사합니다.

안드로이드 오픈톡방 화이팅 <3


참고

서버 응답 Cherry Pick!🍒 (OkHttp Interceptor)

Retrofit Under the Hood

profile
쉽게 가르칠수 있도록 노력하자

0개의 댓글