[Kotlin 개념] 레트로핏 (Retrofit)

이다을·2023년 9월 18일
1

레트로핏 (Retrofit)

안드로이드 개발 시 서버통신에 사용되는 HTTP API를 자바, 코틀린의 인터페이스 형태로 변환해 API를 쉽게 호출할 수 있도록 지원하는 라이브러리입니다.

1. Retrofit이란?

  • Retrofit은 Square Inc.에서 개발한 안드로이드 및 자바를 위한 타입-세이프한 HTTP 클라이언트 라이브러리입니다.
  • REST API의 HTTP 요청을 자바 인터페이스로 변환하는 것을 주 목적으로 합니다.

2. Retrofit의 장점

  • 코드의 간결성
    • 복잡한 HTTP API 요청을 쉽고 간결하게 만들 수 있습니다.
    • 간단한 어노테이션을 통해 요청 메서드와 URL을 정의할 수 있습니다.
  • 안정성과 확장성
    • 내부적으로 OkHttp 라이브러리를 사용하여 통신, 이를 통해 안정적인 통신이 가능합니다.
    • 인터셉터를 사용하여 요청/응답 프로세스를 확장하거나 수정할 수 있습니다.
  • 다양한 플러그인과 컨버터 지원
    • 다양한 데이터 형식(JSON, XML 등)에 대해 데이터 변환 컨버터를 제공합니다.
    • RxJava, Coroutines와 같은 비동기 프로그래밍 라이브러리와 연동 가능합니다.

3. Retrofit 시작하기

  • Gradle에 Retrofit 라이브러리 추가하기
// build.gradle (Module: app)
dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
		implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // Gson 컨버터 추가
		
}
  • manifests에 퍼미션 등록
    • 퍼미션이 등록되어 있어야 네트워킹이 가능합니다.
// AndroidManifest.xml
<user-permission android:name="android.permission.INTERNET"/>

<application
		...
  • Model 클래스 또는 DTO 클래스 만들기
    • 서버로부터 받은 데이터를 담습니다.
    • 만들어줘야 자신들이 알아서 파싱하고 컨버팅 시켜서 담아 줍니다.
// UserModel.kt (data class)
data class UserModel (
		@SerializedName("first_name") // 실제 json 데이터의 키 값
		var firstName: String, // 변수에 넣어줌
		@SerializedName("last_name")
		var lastName: String
)

👉 여기서 잠깐 Gson(JavaScript Object Notation) 이란?

  • Google에서 제공하는 오픈소스 라이브러리로, 웹 상에서 데이터를 주고받을 때 자주 사용되는 경량 데이터 포맷입니다.
  • JSON 데이터를 우리가 사용하는 프로그래밍 언어의 객체로 변환(직렬화 Serialization) 하거나 반대로 객체를 JSON 형태로 변환해야 할 때도 있습니다.(역직렬화 Deserialization) 그때 Gson 라이브러리를 사용하 이러한 작업을 매우 간단하게 해줍니다.

👉 왜 Gson을 사용하는가?

  • 코드의 간결성
    • 일반적으로 JSON을 객체로, 또는 객체를 JSON으로 변환하는 작업은 복잡할 수 있습니다. 그러나 Gson을 사용하면 한 줄의 코드만으로 이러한 변환 작업을 수행할 수 있습니다. 이로 인해 개발자는 복잡한 변환 로직을 작성할 필요 없이, 필요한 작업에 집중할 수 있습니다.
  • 성능 효율성
    • Gson은 내부적으로 최적화된 알고리즘을 사용하여 직렬화 및 역직렬화 작업을 빠르게 수행합니다. 그렇기 때문에 대규모의 데이터나 복잡한 구조의 객체도 효과적으로 처리할 수 있습니다.
  • 광범위한 커뮤니티 지원 및 잘 정리된 문서
    • Gson은 Google에서 개발되어 오랜 시간 동안 많은 개발자들에게 사용되어 왔습니다. 따라서 문제 해결 또는 활용 방안에 관한 다양한 정보와 예제가 인터넷 상에 널려 있습니다. 또한 공식 문서도 매우 잘 정리되어 있어, 필요한 정보를 쉽게 찾아볼 수 있습니다.

👉 Gson 기본 사용법

  • Kotlin 객체를 JSON으로 변환
    val gson = Gson()
    val jsonString = gson.toJson(someObject)
  • JSON을 Kotlin 객체로 변환
    val myClassInstance: MyClass = gson.fromJson(jsonString, MyClass::class.java)

👀 다시 이어서

  • VO 객체 만들기
    • 유저 정보를 포함시킬 수 있는 데이터 정보
// UserListModel.kt (data class)
data class UserModel (
		var data: List<UserModel>?
)
  • API 인터페이스 정의하기
    • 여기서 User는 서버 응답으로 받아올 데이터 모델 클래스입니다.
    • 네트워킹시에 호출한 함수를 가지고 있습니다.
// ApiService.kt (interface)
interface ApiService {
    @GET("api/users")
    fun getUser(@Query("page") page: String): Call<UserListModel> // 콜 객체
}
  • Retrofit 인스턴스 생성하기
    • 이제 apiService 객체를 통해 정의된 API 요청을 사용할 수 있습니다.
// MainActivity.kt
val retrofit = Retrofit.Builder()
    .baseUrl("https://reqres.in/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

// 인터페이스를 레트로핏에 알려줘서 객체 얻기
val apiService = retrofit.create(ApiService::class.java)

4. 응답 처리하기

  • 동기식 vs 비동기식 요청
    • 동기식 요청: 현재 스레드에서 실행되며, 응답이 올 때까지 다음 코드의 실행이 중단됩니다.
    • 비동기식 요청: 콜백을 사용하여 백그라운드에서 실행되며, 응답이 오면 해당 콜백이 호출됩니다.
// MainActivity.kt
val response: Response<User> = apiService.getUser(id).execute()
// MainActivity.kt
// 네트워킹 객체 함수 콜하기
// enqueue 하는 순간 네트워킹 시작
apiService.getUser(page).enqueue(object: Callback<UserListModel> {
    override fun onResponse(call: Call<UserListModel>, response: Response<User>) {
        // 정상적으로 서버 데이터가 넘어오는 순간에 콜되는 함수 처리
				val userList = response.body()
				val mutableList = mutableListOf<Map<String, String>>()
				userList?.data?.forEach {
						val map = mapOf("firstName" to it.firstName, "lastName" to it.lastName)
						mutableList.add(map)
				}
				val adapter = SimpleAdapter(
						mutableList,
						android.R.layout.simple_list_item,
						arrayOf("firstName", "lastName")
						intArrayOf(android.R.id.text1, android.R.id.text2)
				)
				listView.adapter = adapter
    }

    override fun onFailure(call: Call<UserListModel>, t: Throwable) {
        // 서버 연동에 실패 됐을 때 콜 되는 함수란, 오류 처리
				call.cancel()
    }
})

결과 화면


  • 응답 객체 사용하기
    • Response 객체를 통해 HTTP 응답의 여러 정보에 접근할 수 있습니다.
if (response.isSuccessful) {
    val user: User? = response.body()
} else {
    // 오류 메시지 처리
    val error: String = response.errorBody()?.string() ?: "Unknown error"
}
  • 오류 처리하기
    • Retrofit의 onFailure 콜백은 네트워크 오류나 데이터 변환 오류 등에서 호출됩니다.
override fun onFailure(call: Call<User>, t: Throwable) {
    // 오류 메시지 표시
    Log.e("API_ERROR", t.message ?: "Unknown error")
}

5. 컨버터와 인터셉터

  • GSON, Moshi 등의 컨버터 사용하기
    • Retrofit은 자동으로 JSON, XML 등의 응답을 자바/코틀린 객체로 변환하는 기능을 제공합니다.
// GSON 컨버터 사용
val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()
// Moshi 컨버터 사용
val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(MoshiConverterFactory.create())
    .build()
  • 로깅, 헤더 추가 등의 인터셉터 사용하기
    • 인터셉터를 사용하면 요청과 응답의 중간에 원하는 로직을 추가할 수 있습니다.
// Moshi 컨버터 사용
val logging = HttpLoggingInterceptor().apply {
    level = HttpLoggingInterceptor.Level.BODY
}

val client = OkHttpClient.Builder()
    .addInterceptor(logging)
    .addInterceptor { chain ->
        val request = chain.request().newBuilder()
            .addHeader("Authorization", "Bearer YOUR_TOKEN")
            .build()
        chain.proceed(request)
    }
    .build()

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .client(client)
    .addConverterFactory(GsonConverterFactory.create())
    .build()
```![](https://velog.velcdn.com/images/ouowinnie/post/8adb4683-a154-4ef3-b389-839592bb18a4/image.md)
profile
나도 개발 할래

0개의 댓글