okhttp의 역할과 Retrofit과의 관계

HEETAE HEO·2022년 6월 26일
2
post-thumbnail

OkHttp

Okhttp는 REST API, HTTP 통신을 간편하게 구현할 수 있도록 다양한 기능을 제공해주는 라이브러리 입니다.

그리고 Okhttp는 Retrofit이라는 라이브러리의 베이스가 됩니다.

REST API

REST는 Representational State Transfer라는 용어의 약자로서 HTTP의 주요 저자 중 한 사람인 로이 필딩이 그 당시 웹(HTTP) 설계의 우수성에 비해 제대로 사용되지 못하는 모습에 웹의 장점을 최대한 활용할 수 있는 아키텍쳐로 REST를 발표하였고 그 아키텍쳐를 이용해 만든 API를 REST API라고 합니다.

특징을 정리하자면 다음과 같습니다.

  • HTTP 프로토콜 장점을 살릴 수 있는 네트워크 기반 아키텍쳐
  • REST API을 구현하기 위해 HTTP method + 모든 개체 Resource화 + URL 디자인(라우팅)필요합니다.

라우팅이란? 클라이언트의 요청에 대한 결과을 어떻게 이어줄 것인가 하는 처리방법에 대한 것을 말합니다.

  • URI를 이용한 접근 : 모든 개체를 리소스로 보고, 리소스에 고유번호를 부여

  • URL 디자인 원칙 : 자원에 대한 처리를 주소에 나타내지 않는다(HTTP method는 내부적으로 처리하도록), 어떤 자원인지 주소에 명확하게 나타냅니다.

REST의 구성

  • 자원(URI)

  • 메서드(HTTP METHOD)

  • 표현

자원(URI)

URL(Uniform resource Locator) - 통합 자원 식별자로 인터넷에 있는 자원을 나타내는 유일한 주소를 말합니다.

URI(Uniform resource Identifier) - 네트워크 상에서 자원 위치를 알려주기 위한 규약을 말합니다.

메서드

요청의 종류를 서버에 알리기 위해 사용하는 것을 말합니다.

메서드의 종류로는

  1. GET : 정보를 요청하기 위해 사용(Read)
  2. POST : 정보를 입력하기 위해 사용(Create)
  3. PUT : 정보를 업데이트하기 위해 사용(Update)
  4. DELETE : 정보를 삭제하기 위해 사용(Delete)

가 있습니다.

Retrofit

Retrofit는 서버와 클라이언트 간 http 통신을 위한 인터페이스 입니다.

클라이언트가 서버에게 요청을 하고 서버는 클라이언트에 응답을 하는 과정 중간에서 매개체 역할을 해줍니다.

위에서 말한 base가 된다는 것은 뭐죠?

Okhttp는 서버와 HTTP,HTTP/2 프로토콜 통신을 위한 클라이언트 라이브러리인데 만약 Android에서 Okhttp를 사용하지 않고 HTTP로 통신하기 위해서는 다음과 같은 과정을 통해야합니다.

  1. HttpURLConnection 연결
  2. Buffer를 통한 입출력
  3. 예외 처리
    등과 같은 개발자가 많은 부분을 직접 신경을 써야합니다.

하지만 Okhttp는 이러한 부분을 해줍니다. 그래서 사용하는 과정에서 Retrofit을 사용하는데 Retrofit은 type-safe한 HTTP 클라이언트 라이브러리로 내부 코드에서 Okhttp 클라이언트를 디폴트로 선언하기에 base가 된다는 것입니다.

그러면 OkHttp3를 사용안하고 Retrofit만 쓰면 되는거 아니야?? 라고 할 수 있지만 몇 가지 상황에서는 직접 OkHttp를 사용할 필요가 있습니다.

  1. 세부적인 네트워크 구성 요소 제어 : OkHttp를 직접 사용하면 더 많은 컨트롤을 할 수 있습니다. 예를 들어, 커스텀 인터셉터를 사용하여 요청/응답을 수정하거나, 캐싱 전략을 조절하거나, 타임아웃 설정을 변경하는 등의 작업을 수행할 수 있습니다.

// 코드 예시

val httpClient = OkHttpClient.Builder()
    .addInterceptor { chain ->
        val request = chain.request()
        val newRequest = request.newBuilder()
            .header("User-Agent", "MyCustomUserAgent")
            .build()
        chain.proceed(newRequest)
    }
    .cache(Cache(File("cacheDirectory"), 10 * 1024 * 1024))
    .readTimeout(30, TimeUnit.SECONDS)
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .client(httpClient)
    .build()

OkHttpClient.Builder를 사용하여 사용자 정의 인터셉터를 추가하고, 캐시 전략을 설정하며 타임아웃을 설정합니다. 사용자 정의 인터셉터는 User-Agent라는 헤더를 추가했고 캐시 전략은 10MB 크기의 캐시 디렉토리를 사용합니다. 이렇게 함으로써 요청/응답을 수정하거나, 캐싱 전략을 조절하거나, 타임아웃 설정을 변경할 수 있습니다.

  1. 웹소켓 사용 : Retrofit은 HTTP 기반의 API를 지원하지만, 웹소켓을 사용하여 실시간 통신이 필요한 경우 OkHttp를 사용할 수 있습니다. OkHttp는 웹소켓 프로토콜을 지원하므로, 이를 통해 서버와의 실시간 통신을 구현할 수 있습니다.

// 코드 예시

val client = OkHttpClient()
val request = Request.Builder()
    .url("wss://example.com")
    .build()

val listener = object : WebSocketListener() {
    override fun onOpen(webSocket: WebSocket, response: Response) {
        webSocket.send("Hello, WebSocket!")
    }

    override fun onMessage(webSocket: WebSocket, text: String) {
        println("Received message: $text")
    }
}

client.newWebSocket(request, listener)
client.dispatcher.executorService.shutdown()

OkHttp를 사용하여 웹소켓에 연결하고 메시지를 전송 및 수신합니다.웹소켓 리스너를 사용하여 웹소켓 이벤트를 처리할 수 있습니다. 연결이 시작되면 Listener에 설정한 메시지를 출력할 수 있도록 하였습니다. 그 후에는 받는 값을 수신받도록 코드가 작성되어 있습니다.

  1. 중복 요청 제거 : OkHttp의 Dispatcher 클래스를 사용하면 동일한 요청이 중복되는 것을 방지할 수 있습니다. 이를 통해 네트워크 효율을 높일 수 있습니다.
val dispatcher = Dispatcher().apply {
    maxRequestsPerHost = 1
}

val client = OkHttpClient.Builder()
    .dispatcher(dispatcher)
    .build()

val request = Request.Builder()
    .url("https://example.com/")
    .build()

client.newCall(request).enqueue(object : Callback {
    override fun onFailure(call: Call, e: IOException) {
        // Handle error
    }

    override fun onResponse(call: Call, response: Response) {
        // Handle response
    }
})

OkHttpClient.Builder를 사용하여 Dispatcher를 설정합니다. 동일한 호스트에 대한 최대 요청 수를 제한함으로써 중복 요청을 제거할 수 있습니다. 이 경우, 각 호스트에 대한 최대한 요청 수를 1로 설정하여 한번 요청한 호스트에는 재요청을 안하도록 설정할 수 있습니다.

  1. 기타 : OkHttp는 HTTP/2, HTTP/3와 같은 최신 프로토콜을 지원하고, 투명한 GZIP 압축 및 응답 캐싱을 제공합니다. 이러한 고급 기능을 활용하려면 OkHttp를 직접 사용해야 할 수 있습니다.

이러한 상황에서는 Retrofit이 제공하는 기능만으로는 부족하기에 OkHttp를 사용하여 더 많은 제어를 할 필요가 있습니다.

profile
Android 개발 잘하고 싶어요!!!

0개의 댓글