Android

Retrofit2로 JSON 데이터 요청하기

까망사과 2023. 2. 21. 15:00

🔍 Retrofit이란?

Retrofit은 개발자가 정의한 API를 사용하여 HTTP 통신을 할 수 있게 해주는 HTTP 클라이언트 라이브러리다.

HTTP 요청을 통해 XML, JSON 등의 데이터를 받아올 수 있으며 이 포스트에서는 JSON을 다룬다.

 

Retrofit

A type-safe HTTP client for Android and Java

square.github.io

 

🧩 라이브러리 설치하기

모듈 레벨 build.gradle 파일의 dependencies 블럭에 다음 종속 항목들을 추가한다.

  • Retrofit2
    HTTP 통신 작업을 수행한다.
  • 컨버터
    요청한 JSON 데이터를 변환한다. 여러 가지 컨버터가 있으며 여기에서는 GsonConverter를 사용한다.

아래 코드에서는 포스팅 시점 기준 최신 버전을 사용했다.

dependencies {
    ...

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}

 

📜 인터넷 사용 권한 요청하기

Retrofit을 사용하려면 인터넷 사용 권한이 필요하다.

다음처럼 매니페스트 파일에서 INTERNET 권한을 요청하면 된다.

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

    ...
</manifest>

 

🏗️ Retrofit 객체 빌드하기

Retrofit 객체는 아래처럼 빌더 클래스를 사용하여 생성하며 다음 항목들을 설정해야 한다.

  • 베이스 URL
    웹 서비스에서 사용할 기본 URL
  • 컨버터 팩토리
    컨버터를 생성한다.
const val BASE_URL = "https://api.example.com/"
val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .build()

 

🎨 서비스 인터페이스 정의하기

HTTP API는 인터페이스로 정의하며 내부에는 요청 메서드를 정의해야 한다.

요청 메서드는 다음 요소들을 포함해야 한다.

  • HTTP 요청 유형을 나타내는 어노테이션
    아래 나열된 8가지 어노테이션을 사용하여 HTTP 요청 유형을 나타내야 한다.
    • HTTP
    • GET
    • POST
    • PUT
    • PATCH
    • DELETE
    • OPTIONS
    • HEAD
  • 엔드포인트
    위의 HTTP 요청 유형 어노테이션에 엔드포인트를 인자로 전달할 수 있다.
    필요한 경우 중괄호 및 @Path 어노테이션으로 경로 변수를 설정하거나, @Query@QueryMap 어노테이션으로 쿼리 파라미터를 설정할 수 있다.
  • 데이터 모델
    HTTP 응답 본문(body)의 타입을 나타낸다.
    이는 요청 메서드의 반환 타입인 Call의 타입 파라미터로 사용된다.
    Kotlin에서는 데이터 클래스를 사용하여 정의할 수 있으며, 컨버터에서 제공하는 어노테이션을 사용하여 

다음 예시에서 SongServicegetSong()https://api.example.com/song.json에 전송할 GET 요청을 나타내는 Call<Song> 객체를 반환하며, 이에 대한 응답의 본문은 Song 타입으로 변환되어 전달된다.

interface SongService {
    
    @GET("song.json")
    fun getSong(): Call<Song>
}

 

📡 HTTP 요청 전송하고 응답 처리하기

위에서 생성한 Retrofit 객체의 create()에 서비스 인터페이스를 전달하면 해당 인터페이스를 구현하는 인스턴스가 생성된다.

val retrofitService = retrofit.create(SongService::class.java)

 

인터페이스에서 정의한 요청 메서드를 호출하면 Call 객체가 반환되며 다음 메서드들 중 하나를 호출하여 요청을 전송할 수 있다.

  • Call<T>#execute(): Response<T>
    동기적으로 요청을 전송하고 바로 응답을 반환한다.
    타입 파라미터 T는 응답이 성공적일 경우 본문의 타입을 나타낸다.
    오류가 발생하면 예외가 발생한다.
  • Call<T>#enqueue(Callback<T>): Unit
    비동기적으로 요청을 전송하고 응답을 받았을 때 실행할 콜백을 파라미터로 전달한다.
    Callback<T> 인터페이스는 다음 두 가지 콜백 메서드를 포함한다.
    • onResponse(Call<T>, Response<T>)
      응답을 받을 경우 호출
    • onFailure(Call<T>, Throwable)
      요청을 생성 중이거나 응답을 진행 중일 때 오류가 발생할 경우 호출

응답을 받는 데 성공했다면 Response<T>#body()를 호출하여 데이터를 사용할 수 있다.

val call = retroService.getSong()

// 동기적으로 요청을 전송해 응답을 바로 받고자 할 때
try {
    call.execute()
} catch(e: Exception) {
    // TODO: 예외 처리
}

// 비동기적으로 요청을 전송하고자 할 때
call.enqueue(object: Callback<Song>
    override fun onResponse(
        call: Call<Song>,
        response: Response<Song>
    ) {
        // TODO: 응답을 받았을 때 실행할 로직
    }

    override fun onFailure(
        call: Call<Song>,
        t: Throwable
    ) {
        // TODO: 응답을 받지 못했을 때 실행할 로직
    }
)

'Android' 카테고리의 다른 글

LiveData 맛보기  (0) 2023.02.28
ViewModel 맛보기  (0) 2023.02.27
WorkManager (4) : 작업 체이닝  (0) 2022.12.10
WorkManager (3) : 작업 관리하기  (0) 2022.12.05
WorkManager (2) : 작업 상태  (0) 2022.12.02