OkHttp vs Retrofit
둘 다 같은 회사(Square)에서 만든 HTTP 통신 라이브러리이다. OkHttp는 REST API, HTTP 통신을 간편하게 구현할 수 있도록 여러가지 기능을 제공한다. 그리고 이러한 OkHttp를 기반으로 Type-safe하고, 더 직관적으로 사용할 수 있도록 인터페이스로 만들어진 게 Retrofit이다. 따라서 완전히 다르진 않지만, 지원 기능과 용도 면에서 어느정도 차이가 있다.
Retrofit이 OkHttp보다 Type-safe한 이유?
: 개발자가 Json의 Raw한 문자열을 잘못 파싱할 수도 있는 문제를 줄여준다. 또한, 직접 파싱할 필요가 없기 때문에 코드가 간결해지고 편리하다는 장점까지 있다.
다음과 같은 장점의 이유로 OkHttp보다 Retrofit이 더 많이 쓰이고 있다.
1. 어노테이션의 사용
먼저 Retrofit부터 확인해보자. Retrofit에선 BASE URL을 인자로 전달하여 간단하게 객체를 생성한다.
Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build()
다음으로 인터페이스를 생성하고, 원하는 요청 방식과 파라미터에 대해 정의한다.
interface wikiApiServe{
@GET(END_POINT)
fun hitCountCheckCall(
@Query(PARAM_ACTION) action: String,
@Query(PARAM_FORMAT) format: String,
@Query(PARAM_LIST) list: String,
@Query(PARAM_SRSEARCH) srsearch: String)
: Call<Model.Result>
}
이후 네트워크 호출을 할 때마다 미리 정의해놓은 인터페이스 메서드에 필요한 데이터들을 전달해서 호출할 수 있다.
wikiApiServe.hitCountCheckCall(
VALUE_QUERY, VALUE_JSON, VALUE_SEARCH, searchString)
반면 OkHttp에선 다음과 같이 수동으로 요청을 구성해야 한다. 물론 한다면 할 수야 있지만 URL을 입력하는 과정에서 오타가 날 수도 있고, 무엇보다 가독성 면에서 좋지 못하다.
val request = Request.Builder().url("$BASE_URL$BASE_PATH/?" +
"$PARAM_ACTION=$VALUE_QUERY&$PARAM_FORMAT=$VALUE_JSON&" +
"$PARAM_LIST=$VALUE_SEARCH&$PARAM_SRSEARCH=$searchString")
.build()
2. 편리한 Interface 제공
또한, Retrofit은 Call을 반환해주는 Interface를 통해, 직관적이고 간편하게 개발할 수 있도록 도와준다.
interface ProductService {
@GET("/products")
fun getProducts(): Call<List<Product>>
}
하지만 OkHttp에서는 OkHttpClient.newCall(request) 메서드를 호출하여 call을 만들어주어야 하기 때문에, 매번 Request를 만들어주는 작업이 필요하다. Retrofit은 이런 작업을 생략해줄 수 있을 뿐만아니라 Annotation(GET, POST, PATCH 등)을 지정해주어 훨씬 직관적이다.
val okHttpClient = OkHttpClient.Builder() // 1.
.addInterceptor(...)
.build()
val productJson = Gson().toJson(Product(1, "과자")) // 2.
// 서버에 POST 하기 위한 Request Body
// Json 형태의 String을 RequestBody로 변환
val requestBody = productJson.toRequestBody("application/json".toMediaType()) // 3.
// 요청을 위한 Request
val request = Request.Builder().run { // 4.
url("https://localhost:8080/products")
header("Authorization", "Basic {token}")
post(requestBody)
build()
}
okHttpClient.newCall(request).enqueue(object : Callback { // 5.
override fun onFailure(call: Call, e: IOException) {
// Handle this
}
override fun onResponse(call: Call, response: Response) {
val jsonObject = JSONObject(response.body?.string() ?: "{}") // 6.
runOnUiThread {
... // Ui Logic
}
}
})
3. Json <-> Object 자동 변환
다음으로 네트워크 통신 시, 반환되는 응답 객체에 대해 두 라이브러리 간 어떤 차이가 있는지 알아보자. 알다시피 JSON은 자바나 코틀린에서 바로 사용할 수 있는 데이터 형식이 아니기 때문에 JSON을 데이터 클래스로 변환해줄 컨버터를 사용해야 한다. 객체 생성 시 GSON Converter Factory를 연결했다면, Retrofit은 통신 성공 시 응답 객체의 body를 별도의 변환 과정 없이 사용할 수 있다.
call?.enqueue(
object : Callback<Model.Result> {
override fun onFailure(call: Call<Model.Result>, t: Throwable) {
...
}
override fun onResponse(call: Call<Model.Result>,
response: Response<Model.Result>) {
response.body()?.let { //바로 사용 가능 }
}
반면 OkHttp에서는 반환받은 JSON 객체를 데이터 클래스로 바로 변환해주지 못하기 때문에, 별도의 과정을 통해 직접 변환해서 사용해야 한다.
client.newCall(request).enqueue(
object : okhttp3.Callback {
override fun onFailure(call: okhttp3.Call, e: IOException) {
...
}
override fun onResponse(call: okhttp3.Call,
response: okhttp3.Response) {
response.body()?.let {
val result = Gson().fromJson(it.string(),
Model.Result::class.java)
useResult(result)
}
}
)
4. 자동으로 UI 스레드 수행 지원
또한 결과가 반환된 직후 메인스레드에서 바로 사용할 수 있냐 없냐에도 차이가 있다. Retrofit의 경우 enqueue를 사용하면 네트워크 호출이 자동으로 백그라운드에서 이루어진다. 그리고 결과가 반환되면 자동으로 메인스레드에 전달되기 때문에 Toast와 같은 UI 관련 메서드에 결과값을 사용할 수 있다.
override fun onResponse(call: Call<Model.Result>,
response: Response<Model.Result>) {
Toast.makeText(...).show()
})
OkHttp도 enqueue를 사용하면 네트워크 호출이 자동으로 백그라운드에서 수행되지만, 결과가 반환되어도 여전히 백그라운드에 남아있기 때문에 결과값을 메인스레드에서 사용하기 위해서 runOnUiThread를 사용해야 한다.
override fun onResponse(call: okhttp3.Call,
response: okhttp3.Response) {
runOnUiThread {
Toast.makeText(...).show()
}
}
결론적으로 정리해볼 때, Retrofit을 사용하면 OkHttp로는 얻지 못하는 다음의 장점을 느낄 수 있다.
- 어노테이션(Annotation) 사용으로 코드의 가독성이 좋고, 직관적인 설계가 가능하다.
- 통신 결과 값을 JSON으로 변환해줄 필요가 없다.
- 결과 값을 메인스레드에서 바로 사용할 수 있다.
Retrofit은 훌륭한 가독성과 역질렬화할 필요가 없다는 면만 봐도 아주 쓸만한 라이브러리다. 그렇다고 무조건 Retrofit만 사용하는 것은 아니다. Retrofit 역시 HTTP 통신을 할 때 OkHttp에 의존하고 있고, 두 라이브러리 모두 각각 이점을 가지고 있기 때문에(OkHttp의 경우 OkHttpClient에 네트워크 Intercepter를 통해 API가 통신되는 모든 활동을 모니터링 할 수 있으며 서버 통신 시간 조절이 가능하다는 장점이 있다.), 최고의 성능을 내기 위해서 둘 다 사용하는게 보편적이다.
참고한 사이트
https://velog.io/@jeongminji4490/Android-OkHttp-Retrofit
[Android] OkHttp & Retrofit
안드로이드 스튜디오에서 네트워크 작업을 할 때 주로 사용하는 대표적인 라이브러리로 OkHttp, Retrofit이 있다. 요즘은 Retrofit을 주로 쓰고 부가적인 기능을 위해 OkHttpClient를 Retrofit 객체에 연결해
velog.io
https://itstory1592.tistory.com/130
[Android] OkHttp & Retrofit
Android에서 네트워크 작업을 할 때 사용하는 대표적인 라이브러리는 아래와 같다. OkHttp Retrofit 두 라이브러리 모두 Square사에서 개발한 HTTP 통신 라이브러리이다. OkHttp는 HTTP 통신을 간편하게 할
itstory1592.tistory.com
'Android > Retrofit' 카테고리의 다른 글
[Android] Retrofit2 - REST API 통신 라이브러리 (0) | 2023.09.07 |
---|