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을 제공하는 HTTP 애노테이션이 있어야 합니다.
8개의 내장 애노테이션이 있습니다: HTTP
, GET
, POST
, PUT
, PATCH
, DELETE
, OPTIONS
, HEAD
.
리소스의 상대 URL이 애노테이션에 지정됩니다. (상대 URL이란, IP 주소 혹은 도메인 주소 뒤의 부분을 말합니다.)
@GET("users/list")
URL에서 쿼리 매개 변수를 지정할 수도 있습니다.
@GET("users/list?sort=desc")
요청 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>)
@Body
애노테이션을 사용하여 HTTP 요청 본문으로 사용할 객체를 지정할 수 있습니다.
@POST("users/new")
fun createUser(@Body user: User): Call<User>
개체는 Retrofit
인스턴스에 지정된 Converter를 사용하여 변환됩니다. Converter가 추가되지 않은 경우 RequestBody
만 사용할 수 있습니다.
메소드는 폼 인코딩 및 멀티파트 데이터를 전송하도록 선언할 수도 있습니다.
폼 인코딩 데이터는 @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
를 구현하여 자체 직렬화를 처리할 수 있습니다.
@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 인터셉터
를 사용하여 지정할 수 있습니다.
Call
인스턴스는 동기식 또는 비동기식으로 실행될 수 있습니다. 각 인스턴스는 한 번만 사용할 수 있지만 clone()을 호출하면 사용할 수 있는 새 인스턴스가 생성됩니다.
안드로이드에서 콜백은 메인 스레드에서 실행될 것입니다. JVM에서 콜백은 HTTP 요청을 실행한 동일한 스레드에서 발생합니다.
Retrofit
은 API 인터페이스가 호출 가능한 객체로 변환되는 클래스입니다. 기본적으로 Retrofit은 플랫폼에 대한 정상적인 기본값을 제공하지만 사용자 정의를 허용합니다.
기본적으로 Retrofit은 HTTP 본문을 OkHttp의 ResponseBody
유형으로만 역직렬화할 수 있으며 @Body
에 대한 RequestBody
유형만 허용합니다.
Converter를 추가하여 다른 유형을 지원할 수 있습니다. 6개의 형제 모듈은 사용자의 편의를 위해 널리 사용되는 직렬화 라이브러리를 조정합니다.
다음은 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)
Retrofit이 즉시 지원하지 않는 컨텐츠 형식(예: YAML, txt, 사용자 지정 형식)을 사용하는 API와 통신해야 하거나 기존 형식을 구현하기 위해 다른 라이브러리를 사용하고자 하는 경우에는 쉽게 자신만의 컨버터를 만들 수 있습니다. Converter.Factory
를 상속하는 클래스를 만듭니다. 어댑터를 빌드할 때 인스턴스를 팩토리 클래스로 지정하고 통과합니다.