Retrofit

토마스·2023년 6월 5일
0

Retrofit이란?

Retrofit은 HTTP Api를 자바 인터페이스로 변환합니다.

interface GitHubService {
	@GET("users/{user}/repos")
    fun listRepost(@Path("user") user: String): Call<List<Repo>>
}

Retrofit 클래스는 GitHubService 인터페이스의 구현을 생성합니다.

val retrofit: Retrofit = Retrofit.Builder()
	.baseUrl("https://api.github.com/")
    .build()
    
val service: GitHubService = retrofit.create(GitHubService::class.java)

생성된 GitHubService의 각 Call은 원격 웹 서버에 동기식 또는 비동기식 HTTP 요청을 할 수 있습니다.

val repos: Call<List<Repo>> = service.listRepos("octocat")

애노테이션을 사용하여 HTTP 요청을 설명합니다:

  • URL 매개 변수 교체 및 쿼리 매개 변수 지원
  • 요청 본문(예: JSON, 프로토콜 버퍼)으로 객체 변환
  • Multipart request body 및 파일 업로드

API 선언

인터페이스 메서드 및 해당 매개 변수에 대한 애노테이션은 요청이 처리되는 방법을 나타냅니다.

Request Method

모든 메서드에는 요청 메서드와 관련 URL을 제공하는 HTTP 애노테이션이 있어야 합니다.
8개의 내장 애노테이션이 있습니다: HTTP, GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD.
리소스의 상대 URL이 애노테이션에 지정됩니다. (상대 URL이란, IP 주소 혹은 도메인 주소 뒤의 부분을 말합니다.)

@GET("users/list")

URL에서 쿼리 매개 변수를 지정할 수도 있습니다.

@GET("users/list?sort=desc")

URL 조작

요청 URL은 메소드의 대체 블록 및 매개 변수를 사용하여 동적으로 업데이트될 수 있다. 대체 블록은 {}(으)로 둘러싸인 영숫자 문자열입니다. 동일한 문자열을 사용하여 해당 매개 변수에 @Path 애노테이션을 달아야 합니다.

@GET("group/{id}/users")
fun groupList(@Path("id") groupId: Int): Call<List<User>>

쿼리 매개 변수는 추가될 수도 있습니다.

@GET("group/{id}/user")
fun groupList(@Path("id") groupId: Int, @Query("sort") sort: String): Call<List<User>>

복잡한 쿼리 매개 변수 조합의 경우 Map을 사용할 수 있습니다.

@GET("group/{id}/users")
fun groupList(@Path("id") groupId: Int, @QueryMap options: Map<String, String>)

Request Body

@Body 애노테이션을 사용하여 HTTP 요청 본문으로 사용할 객체를 지정할 수 있습니다.

@POST("users/new")
fun createUser(@Body user: User): Call<User>

개체는 Retrofit 인스턴스에 지정된 Converter를 사용하여 변환됩니다. Converter가 추가되지 않은 경우 RequestBody만 사용할 수 있습니다.

FORM ENCODED AND MULTIPART

메소드는 폼 인코딩 및 멀티파트 데이터를 전송하도록 선언할 수도 있습니다.

폼 인코딩 데이터는 @FormUrlEncoded가 메서드에 있을 때 전송됩니다. 각 키-값 쌍에는 이름과 값을 제공하는 개체가 포함된 @Field가 애노테이션으로 표시됩니다.

@FormUrlEncoded
@POST("user/edit")
fun updateUser(@Field("first_name") first: String, @Field("last_name") last: String): Call<User>

멀티파트 요청은 @Multipart가 메서드에 있을 때 사용됩니다. Part는 @Part 애노테이션을 사용하여 선언됩니다.

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
@Multipart
@PUT("user/photo")
fun updateUser(@Part("photo") photo: RequestBody, @Part("description") description: RequestBody): Call<User>

멀티파트의 Part는 Retrofit의 변환기 중 하나를 사용하거나 RequestBody를 구현하여 자체 직렬화를 처리할 수 있습니다.

HEADER 조작

@Headers 애노테이션을 사용하여 메서드에 대한 정적 헤더를 설정할 수 있습니다.

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
fun widgetList(): Call<List<Widget>>
@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
fun getUser(@Path("username") username: String): Call<User>

참고로 헤더는 서로 덮어쓰지 않습니다. 이름이 같은 모든 헤더가 요청에 포함됩니다.

요청 헤더는 @Header 애노테이션을 사용하여 동적으로 업데이트할 수 있습니다. 해당 매개 변수를 @Header에 제공해야 합니다. 값이 null이면 헤더가 생략됩니다. 그렇지 않으면 값에 toString이 호출되고 결과가 사용됩니다.

@GET("user")
fun getUser(@Header("Authorization") authorization: String): Call<User>

쿼리 매개 변수와 유사하게 복잡한 헤더 조합의 경우 Map을 사용할 수 있습니다.

@GET("user")
fun getUser(@HeaderMap headers: Map<String, String>): Call<User>

모든 요청에 추가해야 하는 헤더는 OkHttp 인터셉터를 사용하여 지정할 수 있습니다.

SYNCHRONOUS VS. ASYNCHRONOUS

Call 인스턴스는 동기식 또는 비동기식으로 실행될 수 있습니다. 각 인스턴스는 한 번만 사용할 수 있지만 clone()을 호출하면 사용할 수 있는 새 인스턴스가 생성됩니다.

안드로이드에서 콜백은 메인 스레드에서 실행될 것입니다. JVM에서 콜백은 HTTP 요청을 실행한 동일한 스레드에서 발생합니다.

Retrofit 설정

Retrofit은 API 인터페이스가 호출 가능한 객체로 변환되는 클래스입니다. 기본적으로 Retrofit은 플랫폼에 대한 정상적인 기본값을 제공하지만 사용자 정의를 허용합니다.

CONVERTERS

기본적으로 Retrofit은 HTTP 본문을 OkHttp의 ResponseBody 유형으로만 역직렬화할 수 있으며 @Body에 대한 RequestBody 유형만 허용합니다.

Converter를 추가하여 다른 유형을 지원할 수 있습니다. 6개의 형제 모듈은 사용자의 편의를 위해 널리 사용되는 직렬화 라이브러리를 조정합니다.

  • Gson: com.squareup.retrofit2:converter-gson
  • Jackson: com.squareup.retrofit2:converter-jackson
  • Moshi: com.squareup.retrofit2:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire
  • Simple XML: com.squareup.retrofit2:converter-simplexml
  • JAXB: com.squareup.retrofit2:converter-jaxb
  • Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars

다음은 GsonConverterFactory 클래스를 사용하여 Gson을 역직렬화에 사용하는 GitHubService 인터페이스 구현을 생성하는 예입니다.

val retrofit: Retrofit = Retrofit.Builder()
	.baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()
    
val service: GitHubService = retrofit.create(GitHubService::class.jave)

CUSTOM CONVERTERS

Retrofit이 즉시 지원하지 않는 컨텐츠 형식(예: YAML, txt, 사용자 지정 형식)을 사용하는 API와 통신해야 하거나 기존 형식을 구현하기 위해 다른 라이브러리를 사용하고자 하는 경우에는 쉽게 자신만의 컨버터를 만들 수 있습니다. Converter.Factory를 상속하는 클래스를 만듭니다. 어댑터를 빌드할 때 인스턴스를 팩토리 클래스로 지정하고 통과합니다.

profile
안드로이드 개발자 지망생

0개의 댓글