Skip to content

Files

Latest commit

40f4477 Β· Aug 30, 2018

History

History
232 lines (140 loc) Β· 7.68 KB

retrofit.md

File metadata and controls

232 lines (140 loc) Β· 7.68 KB

Retrofit

Present time : 2018-07-06 Fri


Last Updated :



0. 곡식 λ¬Έμ„œ

0-1. 곡식 λ¬Έμ„œ

0-2. κ°€μ΄λ“œ

  • ​


1. μ†Œκ°œ

  • Retrofit은 HTTP APIλ₯Ό μžλ°” μΈν„°νŽ˜μ΄μŠ€ ν˜•νƒœλ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Java 7 이상, Android 2.3 μ΄μƒμ—μ„œλ§Œ μ‚¬μš©κ°€λŠ₯ν•©λ‹ˆλ‹€.

HTTP μš”μ²­μ€ μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜μ—¬ λͺ…μ‹œν•©λ‹ˆλ‹€.

  • URL νŒŒλΌλ―Έν„° μΉ˜ν™˜κ³Ό 쿼리 νŒŒλΌλ―Έν„°κ°€ μ§€μ›λ©λ‹ˆλ‹€.
  • 객체λ₯Ό μš”μ²­ body둜 λ³€ν™˜ν•©λ‹ˆλ‹€. (예: JSON, protocol buffers)
  • λ©€ν‹°νŒŒνŠΈ μš”μ²­ body와 파일 μ—…λ‘œλ“œκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.


2. API μ •μ˜

μΈν„°νŽ˜μ΄μŠ€μ˜ μ–΄λ…Έν…Œμ΄μ…˜κ³Ό λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜λ“€μ€ μš”μ²­μ„ μ–΄λ–»κ²Œ λ‹€λ£°μ§€ μ§€μ‹œν•©λ‹ˆλ‹€.

2-1. μš”μ²­ λ©”μ†Œλ“œ

λͺ¨λ“  λ©”μ†Œλ“œλ“€μ€ λ°˜λ“œμ‹œ μƒλŒ€ URLκ³Ό μš”μ²­ λ©”μ†Œλ“œλ₯Ό λͺ…μ‹œν•˜λŠ” μ–΄λ…Έν…Œμ΄μ…˜μ„ κ°€μ§€κ³  μžˆμ–΄μ•Όν•©λ‹ˆλ‹€. 기본으둜 μ œκ³΅ν•˜λŠ” μš”μ²­ λ©”μ†Œλ“œ μ–΄λ…Έν…Œμ΄μ…˜μ€ λ‹€μŒκ³Ό 같이 5κ°œκ°€ μžˆμŠ΅λ‹ˆλ‹€ : GET, POST, PUT, DELETE, HEAD.


정적 쿼리 인자λ₯Ό URL에 λͺ…μ‹œν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

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

2-2. URL 닀루기

μš”μ²­ URL은 λ™μ μœΌλ‘œ λΆ€λΆ„ μΉ˜ν™˜ κ°€λŠ₯ν•˜λ©°, μ΄λŠ” λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜λ‘œ 변경이 κ°€λŠ₯ν•©λ‹ˆλ‹€. λΆ€λΆ„ μΉ˜ν™˜μ€ 영문/숫자둜 이루어진 λ¬Έμžμ—΄μ„ { 와 } 둜 감싸 μ •μ˜ν•΄μ€λ‹ˆλ‹€. λ°˜λ“œμ‹œ 이에 λŒ€μ‘ν•˜λŠ” @Path λ₯Ό λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜μ— λͺ…μ‹œν•΄μ€˜μ•Όν•©λ‹ˆλ‹€.

@GET("/group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

이외에도 쿼리 λ§€κ°œλ³€μˆ˜λ„ λͺ…μ‹œ κ°€λŠ₯ν•©λ‹ˆλ‹€. @Query와 @QueryMap을 μ΄μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.


2-3. μš”μ²­ λ³Έλ¬Έ

HTTP μš”μ²­ 본문에 객체λ₯Ό @Body μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 λͺ…μ‹œκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.

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

μ΄λŸ¬ν•œ 객체듀은 Retrofit μΈμŠ€ν„΄μŠ€μ— μΆ”κ°€λœ 컨버터에 따라 λ³€ν™˜λ©λ‹ˆλ‹€. λ§Œμ•½ ν•΄λ‹Ή νƒ€μž…μ— λ§žλŠ” 컨버터가 μΆ”κ°€λ˜μ–΄μžˆμ§€ μ•Šλ‹€λ©΄, RequestBody 만 μ‚¬μš©ν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.


FORM-ENCODEDκ³Ό MULTIPART

λ©”μ†Œλ“œλŠ” form-encoded 데이터와 multipart 데이터 λ°©μ‹μœΌλ‘œ μ •μ˜ κ°€λŠ₯ν•©λ‹ˆλ‹€.


@FormUrlEncoded μ–΄λ…Έν…Œμ΄μ…˜μ„ λ©”μ†Œλ“œμ— λͺ…μ‹œν•˜λ©΄ form-encoded λ°μ΄ν„°λ‘œ 전솑 λ©λ‹ˆλ‹€. 각 key-value pair의 keyλŠ” μ–΄λ…Έν…Œμ΄μ…˜ 값에, valueλŠ” 객체λ₯Ό μ§€μ‹œν•˜λŠ” @Field μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ λ§€κ°œλ³€μˆ˜μ— λͺ…μ‹œν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€.

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

Multipart μš”μ²­μ€ @Multipart μ–΄λ…Έν…Œμ΄μ…˜μ„ λ©”μ†Œλ“œμ— λͺ…μ‹œν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€. 각 νŒŒνŠΈλ“€μ€ @Part μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ λͺ…μ‹œν•©λ‹ˆλ‹€.

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

Multipart의 partλŠ” Retrofit 의 μ»¨λ²„ν„°λ‚˜, RequestBody λ₯Ό ν†΅ν•˜μ—¬ 직렬화(serialization) κ°€λŠ₯ν•œ 객체λ₯Ό μ‚¬μš©ν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.


2-4. 헀더 닀루기

2-4-1. 정적 헀더

정적 헀더듀은 @Headers μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 λͺ…μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

@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);

2-4-2. 동적 헀더

동적인 ν—€λ”λŠ” @Header μ–΄λ…Έν…Œμ΄μ…˜μ„ 톡해 λͺ…μ‹œ κ°€λŠ₯ν•©λ‹ˆλ‹€. λ°˜λ“œμ‹œ 이에 λŒ€μ‘ν•˜λŠ” @Header μ–΄λ…Έν…Œμ΄μ…˜μ„ λ§€κ°œλ³€μˆ˜μ— λͺ…μ‹œν•΄μ•Όν•©λ‹ˆλ‹€. λ§Œμ•½ 값이 null이라면 ν•΄λ‹Ή ν—€λ”λŠ” μΆ”κ°€λ˜μ§€μ•ŠμŠ΅λ‹ˆλ‹€. μ•„λ‹ˆλΌλ©΄, λ§€κ°œλ³€μˆ˜ 객체의 toString λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ λ°˜ν™˜λœ 값을 ν—€λ”μ˜ κ°’μœΌλ‘œ μΆ”κ°€ν•©λ‹ˆλ‹€.

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

2-5. 동기 VS. 비동기

Call μΈμŠ€ν„΄μŠ€λŠ” 동기 ν˜Ήμ€ λΉ„λ™κΈ°λ‘œ μš”μ²­ 싀행이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 각 μΈμŠ€ν„΄μŠ€λ“€μ€ 동기 ν˜Ήμ€ 비동기쀑 ν•œκ°€μ§€ λ°©μ‹λ§Œ μ‚¬μš©κ°€λŠ₯ν•©λ‹ˆλ‹€, ν•˜μ§€λ§Œ clone() λ©”μ†Œλ“œλ₯Ό 톡해 μƒˆ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ‹œλ©΄ 이전과 λ‹€λ₯Έ 방식을 μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.

μ•ˆλ“œλ‘œμ΄λ“œμ—μ„œμ˜ μ½œλ°±λ“€μ€ 메인 μŠ€λ ˆλ“œμ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€. JVMμ—μ„œλŠ”, HTTP μš”μ²­μ„ ν˜ΈμΆœν•œ μŠ€λ ˆλ“œμ™€ λ™μΌν•œ μŠ€λ ˆλ“œμ—μ„œ μ½œλ°±λ“€μ΄ μ‹€ν–‰λ©λ‹ˆλ‹€.


μš°μ„  자주 μ‚¬μš© 될 λ²•ν•œ 비동기식 λ°©μ‹μ˜ 톡신은 μœ„μ—μ„œ 이미 μ‚¬μš©ν•΄ λ³Έ enqueue() methodλ₯Ό μ΄μš©ν•˜λŠ” 것 μž…λ‹ˆλ‹€.

κ·Έλ ‡λ‹€λ©΄ λ°˜λŒ€λ‘œ 동기식 λ°©μ‹μ˜ 톡신을 ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒμš”?

μƒμ„±λœ ν΄λΌμ΄μ–ΈνŠΈ 객체가 μ œκ³΅ν•˜κ³  μžˆλŠ” execute() methodλ₯Ό enqueue() method λŒ€μ‹  μ΄μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.



3. Retrofit μ„€μ •

3-1. 컨버터

기본적으둜, Retrofit은 HTTP μš”μ²­ 본문을 OkHttp의 ResponseBody ν˜•μ‹κ³Ό @Body 에 μ΄μš©ν•˜λŠ” RequestBody νƒ€μž…λ§Œ 역직렬화(deserialization) ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

컨버터듀은 μ΄μ™Έμ˜ ν˜•μ‹λ“€μ„ λ³€ν™˜ν•΄μ£ΌλŠ” 역할을 ν•©λ‹ˆλ‹€. μ•„λž˜μ— 많이 μ‚¬μš©ν•˜κ³  νŽΈλ¦¬ν•œ 컨버터 6개의 λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ„ μ‚¬μš©ν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi
  • Protobuf: com.squareup.retrofit:converter-protobuf
  • Wire: com.squareup.retrofit:converter-wire
  • Simple XML: com.squareup.retrofit:converter-simplexml

μ˜ˆμ‹œ

Gson을 μ‚¬μš©ν•˜λŠ” GitHubService μΈν„°νŽ˜μ΄μŠ€κ°€ Gson을 역직렬화가 κ°€λŠ₯ν•˜κ²Œ GsonConverterFactory 클래슀λ₯Ό 톡해 컨버터λ₯Ό μΆ”κ°€ν•˜λŠ” μ˜ˆμ œμž…λ‹ˆλ‹€.

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

GitHubService service = retrofit.create(GitHubService.class);

addConverterFactory() methodλ₯Ό 톡신이 μ™„λ£Œλœ ν›„, μ–΄λ–€ Converterλ₯Ό μ΄μš©ν•˜μ—¬ 데이터λ₯Ό νŒŒμ‹±ν•  것인지에 λŒ€ν•œ μ„€μ •μž…λ‹ˆλ‹€.


μ£Όμ˜ν•  점!

κ³΅μ‹λ¬Έμ„œμƒμ—λŠ” baseURL()에 μ„€μ •λœ μ„œλ²„ URL에 /κ°€ μ—†μŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ‹€μ§ˆμ μœΌλ‘œ μ—¬λŸ¬κ°€μ§€ 톡신을 ν•˜λ©΄μ„œ λ‘œκΉ…μ„ 해보면 baseURL()에 /κ°€ 없을 경우, μš”μ²­ λ˜μ–΄μ•Ό ν•  URL의 일뢀가 μž˜λ €λ‚˜κ°€λŠ” ν˜„μƒμ΄ λ°œμƒν•˜μ—¬ 잘λͺ»λœ 경둜둜 μš”μ²­ν•˜λŠ” ν˜„μƒμ΄ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‹ˆ κΌ­ baseURL()에 μ„€μ •λ˜λŠ” URL의 λ§ˆμ§€λ§‰ κ²½λ‘œμ—λŠ” /λ₯Ό ν•¨κ»˜ 포함해 주도둝 ν•΄μ•Όν•©λ‹ˆλ‹€!


3-2. μ‚¬μš©μžμ •μ˜ 컨버터

λ§Œμ•½ API와 ν†΅μ‹ ν•˜λŠ”λ° Retrofit이 μ§€μ›ν•˜μ§€ μ•ŠλŠ” ν˜•μ‹(e.g. YAML, txt, custom format) μ΄κ±°λ‚˜ ν˜„μž¬ μ‚¬μš©κ°€λŠ₯ν•œ ν˜•μ‹μ΄μ§€λ§Œ λ‹€λ₯Έ 라이브러리λ₯Ό 톡해 κ΅¬ν˜„ν•˜μ‹œκΈΈ μ›ν•˜μ‹ λ‹€λ©΄, μ‰½κ²Œ λ‚˜λ§Œμ˜ 컨버터λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. Converter.Factory λ₯Ό μƒμ†ν•˜μ—¬ λ§Œλ“œμ‹œκ³ , 이λ₯Ό Retrofit 객체λ₯Ό λ§Œλ“œμ‹€λ•Œ μΆ”κ°€ν•˜μ‹œλ©΄λ©λ‹ˆλ‹€.


Proguard

λ§Œμ•½ ν”„λ‘œμ νŠΈκ°€ Proguardλ₯Ό μ‚¬μš©ν•˜μ‹œλ©΄ μ•„λž˜ λ‚΄μš©μ„ 섀정에 μΆ”κ°€ν•˜μ‹­μ‹œμ˜€.

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions