본문
171218(월) - Retrofit
Retrofit
Request method
@GET
@Documented @Target(value=METHOD) @Retention(value=RUNTIME) public @interface GET
Make a GET request.
@POST
@Documented @Target(value=METHOD) @Retention(value=RUNTIME) public @interface POST
Make a POST request.
@PUT
@Documented @Target(value=METHOD) @Retention(value=RUNTIME) public @interface PUT
Make a PUT request.
@DELETE
@Documented @Target(value=METHOD) @Retention(value=RUNTIME) public @interface DELETE
Make a DELETE request.
@HEAD
@Documented @Target(value=METHOD) @Retention(value=RUNTIME) public @interface HEADMake a HEAD request.
URL Manipulation
- { and } 로 replacement block 생성 가능
- 대응되는 parameter는 @Path 로 annotated 되어야 한다.
@GET("group/{id}/users") Call<List<User>> groupList(@Path("id") int groupId);
- Query parameter도 추가 가능
@GET("group/{id}/users") Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
@Query
- URL에 추가된 Query parameter
- Retrofit.stringConverter(Type, Annotation[])
(or Object.toString())
에 의해 String으로 변환된 다음 URL로 encoded된다.
- null value are ignored
- List or Array를 전달하면 non-null item 각각에 대한 query parameter가 생성
@GET("/friends")
Call<ResponseBody> friends(@Query("page") int page);
foo.friends(1)
/friends?page=1
foo.friends(null)
/friends
@GET("/friends")
Call<ResponseBody> friends(@Query("group") String... groups);
foo.friends("coworker", "bowling")
/friends?group=coworker&group=bowling
@GET("/friends")
Call<ResponseBody> friends(@Query(value="group", encoded=true) String group);
foo.friends("foo+bar"))
/friends?group=foo+bar
- complex query parameter combinations a Map can used
@GET("group/{id}/users") Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
- Retrofit.stringConverter(Type, Annotation[])
(or Object.toString())
에 의해 String으로 변환된 다음 URL로 encoded된다.
@GET("/friends")
Call<ResponseBody> friends(@QueryMap Map<String, String> filters);
foo.friends(ImmutableMap.of("group", "coworker", "age", "42"))
/ friends?group=coworker&age=42
- null은 허용하지 않는다.
Request Body
- @Body로 HTTP request body 사용
@POST("users/new") Call<User> createUser(@Body User user);
@Body
- POST/PUT 시에 request body를 directly control 하고 싶을 때 사용
- Retrofit instance에 의해서 serialized 되며 결과는 request body로 직접 set 된다.
- Body가 null일 수 없다.
Form Encoded and Multipart
- method에 @FromUrlEncoded가 있으면 Form-encoded data가 전송된다.
- each key-value에는 name을 포함하는 @Field와 value를 제공하는 object가 annotation으로 표시
@FormUrlEncoded @POST("user/edit") Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@FormUrlEncoded
- request body from이 URL encoding 형식이라는것을 나타냄
- field는 @Field로 선언
@Field
- form-encoded request의 pair
- Retrofit.stringConverter(Type, Annotation[])
(or Object.toString())
에 의해 String으로 변환된 다음 URL로 encoded된다.
- null은 허용되지 않는다.
- List or Array를 전달하면 non-null item 각각에 대한 field pair가 생성
@FormUrlEncoded
@POST("/")
Call<ResponseBody> example(
@Field("name") String name,
@Field("occupation") String occupation);
foo.example("Bob Smith", "President")
name=Bob+Smith&occupation=President
@FormUrlEncoded
@POST("/list")
Call<ResponseBody> example(@Field("name") String... names);
foo.example("Bob Smith", "Jane Doe")
name=Bob+Smith&name=Jane+Doe
- method에 @Multipart가 있을 때 Multipart request used.
- part는 @Part annotation을 사용
@Multipart @PUT("user/photo") Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
- multipart는 Retrofit's converters를 사용하거나 RequestBody를 implement하여 serialization 가능
@Multipart
- request body가 multi-part 일 때 사용
- part는 parameter로 @Part로 선언
@Part
- multipart의 single part를 나타냄
- parameter type processed ways
1. MultipartBody.Part
- content가 directly used
- annotation에서 이름 생략
- @Part MultipartBody.Part part
2. RequestBody
- content type 과 함께 directly used
- annotation에 part name을 제공해라
- @Part("foo") RequestBody foo
3. other object type
- converter를 사용하여 적절하게 변경
- annotation에 part name을 제공해라
- @Part("foo") Image photo
- value는 null일 수 있고 request body 생략 가능
@Multipart
@POST("/")
Call<ResponseBody> example(
@Part("description") String description,
@Part(value = "image", encoding = "8-bit") RequestBody image);
- part parameters not be null
Header Manipulation
- @Headers annotation을 사용해서 static headers를 set 가능하다.
@Headers("Cache-Control: max-age=640000") @GET("widget/list") Call<List<Widget>> widgetList();
@Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) @GET("users/{username}") Call<User> getUser(@Path("username") String username);
- header는 서로 overwrite 하지 않는다.
- 같은 이름의 모든 header가 request에 포함
- request header는 @Header annotation을 사용하여 dynamically update 가능
- value가 null이면 omitted.
- value가 non-null이면 toString이 value로 called되어 사용
@GET("user") Call<User> getUser(@Header("Authorization") String authorization)
- all header는 OkHttp intercepter를 사용해서 지정할 수 있습니다.
@Headers
- headers 값 추가
- headers는 겹쳐 쓰지 않는다.
@Headers("Cache-Control: max-age=640000")
@GET("/")
...
@Headers({
"X-Foo: Bar",
"X-Ping: Pong"
})
@GET("/")
...
@Header
- replaces headers value
- header parameter는 nullable해서 omit 가능하다.
- list를 전달하면 non-null item에 대해서 header가 생성
- header는 겹쳐쓰지 않는다.
@GET("/")
Call<ResponseBody> foo(@Header("Accept-Language") String lang);
Synchronous vs Asynchronous
- Call instance는 synchronously or asynchronously 실행 가능
- 각 instance는 한번만 사용 가능하지만, clone()을 호출하면 새 instance가 만들어진다.
- Android에서는 callback이 main thread에서 executed된다.
- JVM에서 callback은 HTTP request를 executed한 동일한 thread에서 발생
Call<T>
- retrofit method를 call하여 web server에 request를 보내고 response를 return한다.
- 각 call은 HTTP request and response pair를 가진다.
- 동일한 web server에 동일한 parameter를 사용해서 여러번 호출하려면 clone() 사용
- clone() 은 polling or retry a fail call에 유용
- synchronously execute with execute()
- asynchronously execute with enqueue(retrofit2.Callback<T>)
- 위 두경우 모두 cancel()
로 call cancel 가능하다.
- request writing or response reading가 busy이면 IOException
receive
Retrofit Configuration
- retrofit는 callable object로 변환되는 class
- 기본적으로 platform에 맞게 제공되지만 customization 가능하다.
Converters
- 기본적으로 HTTP body를 OkHttp의 ResponseBody 형식으로 deserialize 할 수 있으며, @Body에 대한 RequestBody 형식만 수락 가능
- 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
- Scalars (primitives, boxed, and String):
com.squareup.retrofit2:converter-scalars
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .build(); GitHubService service = retrofit.create(GitHubService.class);
Custom converters
- extends Converter.Factory
class , adapter를 build할 때 instance를 pass하는 class를 만든다.
댓글