CS/Android

Retrofit

졔졔311 2025. 2. 16. 10:55
728x90
반응형

retrofit이란

android에서 REST API와 통신하기 위한 네트워크 라이브러리.

HTTP 요청을 더 쉽게 만들며, 응답을 model 객체로 변환할 수 있다.

Jetpack Compose는 UI Framework이므로, 네트워크 라이브러리인 Retrofit을 사용할 수 있는데
이 과정에서 ViewModel과 함께 사용하면 API 데이터를 UI에 반영할 수 있다.

코드가 간결하고, 유지보수가 쉬워 REST API 호출 시 가장 많이 쓰인다.

 

장단점

ㅇ 장점

1. 간결하고 직관적인 코드 : 인터페이스로 API를 정의하고, annotation을 사용해 간편한 API 요청 가능.

(OkHttp에 비해 코드가 깔끔)

2. Coroutine/Callback 등의 비동기 처리 지원

- Coroutine 기반 비동기 처리 : suspend fun 사용

- 콜백 방식 : enqueue()

- RxJava 지원

3. 자동 JSON 변환 : JSON 응답을 자동으로 데이터 클래스에 매핑 -> 파싱 편리

(Gson, Moshi, Kotlinx Serialization 등 사용 가능)

4. 동적 URL, query parameter 지원

- {}를 사용한 동적 엔드포인트 설정

- @Query로 query parameter 추가 가능

5. OkHttp와 조합 가능 : 네트워크 로깅, header 조작, 캐싱 등 기능 추가 가능

 

ㅇ 단점

1. GraphQL 지원 부족

- REST API에는 최적화, 그러나 GraphQL 같은 API에는 맞지x

- Apollo GraphQL 등의 라이브러리 사용 필요

2. 대용량 데이터 처리 overhead

- JSON 자동 변환 시 메모리 사용량 증가

- 대량의 데이터 처리를 위해 streaming 방식 필요

3. 복잡한 API 요청 구성 시 복잡도 증가

- 파일 업로드 / 멀티파트 요청 등은 코드가 복잡해짐 -> OkHttp 사용

 

* retrofit2?

Square에서 개발한 REST API 통신 라이브러리.

Retrofit1을 개선한 버전. OkHttp 기반으로 동작함.

성능과 유연성이 더 좋아짐.

  Retrofit1 Retrofit2
기반 HttpURLConnection OkHttp
비동기 방식 내부적으로 AsyncTask 사용 Call.enqueue(), Coroutine, RxJava 지원
에러 처리 예외 발생 Response<T>로 성공/실패 구분 가능
JSON 변환 GsonConverter만 지원 Gson뿐만 아니라 Moshi, Kotlinx Serialization 등 다양한 컨버터 지원
CallBack 인터페이스 전역 설정 가능 개별 요청마다 Call 객체 사용

 

사용법 (with. jetpack compose)

1. retrofit 라이브러리 추가

- app 모듈의 build.gradle.kts : dependency 추가

dependencies {
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.squareup.retrofit2:converter-gson:2.9.0") // JSON 변환기
}

 

* gson 변환기?

API 응답을 자동으로 JSON에서 데이터 클래스로 변환해주는 역할

 

2. API 인터페이스 정의 : HTTP 요청 (GET, POST 등)

여기서는 제일 단순한 GET 요청을 기준으로 작성하였다.(POST method와 posts는 관련 없음)

import retrofit2.http.GET

interface ApiService {
    @GET("posts")  // API 엔드포인트 posts - HTTP GET 요청
    suspend fun getPosts(): List<Post>	// suspend fun : coroutine을 사용한 비동기 처리
}

 

 

 

3. 데이터 모델 생성 : API 응답을 받아올 데이터 클래스

import com.google.gson.annotations.SerializedName

data class Post(
    val id: Int,
    val title: String,
    @SerializedName("body") val content: String	// @SerializedName() : JSON 필드명과 변수명 매칭
)

 

 

 

4. Retrofit 객체 생성 : API 기본 설정

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
    private const val BASE_URL = "https://jsonplaceholder.typicode.com/"

    val api: ApiService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create()) // JSON 자동 변환
            .build()
            .create(ApiService::class.java)
    }
}

 

 

5. ViewModel에서 API 호출 - StateFlow 활용

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class PostViewModel : ViewModel() {
    // Compose에서 UI 업데이트를 쉽게 하기 위해 MutableStateFlow 사용
    private val _posts = MutableStateFlow<List<Post>>(emptyList())
    val posts: StateFlow<List<Post>> = _posts

    init {
        fetchPosts()
    }

    private fun fetchPosts() {
        viewModelScope.launch {	// ViewModel에서 비동기 네트워크 호출을 실행하기 위해
            try {
                _posts.value = RetrofitInstance.api.getPosts()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

 

 

6. jetpack compose UI에서 데이터 표시 - Flow data binding

import androidx.compose.runtime.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.*
import androidx.compose.material3.*
import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun PostScreen(viewModel: PostViewModel = viewModel()) {
    val posts by viewModel.posts.collectAsState()	// Flow 데이터를 관찰해 UI를 업데이트 함

    LazyColumn {	// 리스트 형태로 API 데이터 출력
        items(posts) { post ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(8.dp)
            ) {
                Column(modifier = Modifier.padding(16.dp)) {
                    Text(text = post.title, style = MaterialTheme.typography.titleLarge)
                    Text(text = post.content, style = MaterialTheme.typography.bodyMedium)
                }
            }
        }
    }
}

 

 

출처 : Retrofit

728x90
반응형