본문 바로가기
개발/Android

[Android] Retrofit - API 통신을 쉽게 구현해보자

by tempus 2021. 12. 16.
반응형

Android 개발에서 가장 많이 쓰는 라이브러리라고 하면 Retrofit은 빠질 수 없을 겁니다. 이번에는 이 Retrofit이 정확히 무엇인지 정리해보려고 합니다.

 

Retrofit


홈페이지에 가면 Retrofit을 다음과 같이 정의하고 있습니다.

A type-safe HTTP client for Android and Java

번역하면 Android, Java용 Type-Safe HTTP 클라이언트입니다. 즉, 서버와 클라이언트 간 HTTP 통신을 쉽게 해주는 라이브러리입니다. 기본적으로 백그라운드에서 실행되며 callback을 통해 Main Thread에서 UI 업데이트를 간단히 할 수 있습니다. 하지만 보통 이 방법보다는 RxJava, Coroutine와 같이 구현하는 방식을 선호하고 있습니다. (유지 보수성과 예외 처리 부분에서 더 효율적)

 

Retrofit을 통해 우리는 JSON 또는 XML 데이터를 쉽게 처리가 가능하고 POJO(순수한 자바 객체)로 파싱 됩니다. HTTP Method인 GET, POST, PUT, PATCH, DELETE를 모두 실행할 수 있습니다.

 

Retrofit를 왜 사용하는가?

📀 안드로이드 통신의 간단한 역사?

초기 안드로이드 통신은 HttpClient를 사용했습니다. 그러다가 버그로 인해 HttpUrlConnection이 권장되어 사용되었지만 사용법이 복잡하다는 문제가 있었습니다. 이후로 Google에서 만든 Volley가 나와서 표준 라이브러리처럼 사용되었습니다.

하지만 안드로이드 5.1(롤리팝)에서 HttpClient가 Deprecated 된 후, HttpClient에 의존하던 Volley도 Deprecated 되었습니다. 이로 인해 Square에서 만들어진 라이브러리인 OkHttp와 그 래퍼인 Retrofit이 하나의 필수적인 라이브러리로 자리매김하게 되었습니다.

 

📀 Retrofit 장점

기본적으로 서버와 통신을 하려면 HTTP 통신을 해야 했습니다. 기본적으로 HttpUrlConnection을 이용하면 매번 connection 설정 등 반복적인 작업이 발생하게 됩니다. 이때 이것을 도와주는 라이브러리가 OkHttp입니다. 하지만 OkHttp는 사용 시 대개 Asynctask를 통해 비동기로 실행하게 되는데 성능상 느리다는 이슈 발생하였습니다.

반면에 Retrofit은 Asynctask를 사용하지 않고 자체적인 비동기 실행과 스레드 관리를 통해 속도가 많이 개선되었다. 또한 Retrofit에서는 Request, Response 설정 등 반복적인 작업을 라이브러리에서 넘겨서 처리하므로 작업량이 줄어들고 사용하기 굉장히 편리합니다.

 

그래서 Retrofit의 장점을 요약 하지면 속도, 편의성, 가독성이라고 할 수 있습니다.

 

Retrofit 기본 사용법

여기서는 기본적인 callback방식으로 Retrofit을 어떻게 사용하는지 간단히 알아보고 추후에 RxJavaCoroutine을 결합하여 사용하는 방법을 다루도록 하겠습니다.

 

Android에서는 아래와 같이 gradle에 추가하면 사용할 수 있습니다. converter-gson 은 응답 결과가 JSON일 때 객체로 변화해주기 위해 추가해줍니다.

implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.6.0'

 

네트워크 통신을 위해서 AndroidManifest.xml에 다음을 추가합니다.

<uses-permission android:name="android.permission.INTERNET" />

 

그다음으로는 Model역할을 할 Data class를 만들어줍니다. @SerializedName는 Gson이 JSON 키를 필드에 매핑하기 위해서 필요합니다.

data class User(
    @SerializedName("id")
    val id: String? = null,
    @SerializedName("name")
    val name: String? = null,
    @SerializedName("year")
    val year: Int? = null,
)

 

API Interface를 만들고 해당하는 Interface의 Retrofit 인스턴스를 만들어줍니다. companion object는 단순히 클래스 이름을 식별자로 사용함으로써 Java나 C#에서 static 메소드를 호출했던 것과 같이 해당 객체를 사용할 수 있습니다.

interface UserService {

    @GET("/User")
    fun getUserById(
        @Query("id") id : String?,
    ) : Call<User>

    companion object{
        private const val BASE_URL = "https://test.io/"

        private val gson =
            GsonBuilder()
                .setLenient()
                .create()

        fun create() : BookService{
            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(OkHttpClient.Builder().build())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build()
                .create(UserService::class.java)
        }
    }
}

 

이제 호출하고 싶은 Activity나 Fragment에서 다음과 같이 호출하면 됩니다. 여기서는 MainActivity에서 호출하겠습니다.

UserService.create().getUserById("ids").enqueue(object : Callback<User>{
                override fun onFailure(call: Call<User>, t: Throwable) {
                               Toast.makeText(this@MainActivity, t.message, Toast.LENGTH_SHORT).show()
                }
                override fun onResponse(call: Call<User>, response: Response<User>) {
                    if (response.isSuccessful) {
                        val data = response.body()
                        if (data != null) {
                    		/**
                  				데이터 처리
                    		**/
                        }
                    }
                }
            })

 

 

Reference

반응형

댓글


loading