๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Android] Retrofit2 ๊ธฐ๋ณธ ์„ค๋ช…

์ถœ์ฒ˜

ChatGPT


Retrofit2๋Š” Android ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ RESTful API์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” HTTP ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. Retrofit2๋Š” ๊ฐ„๋‹จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ API ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , JSON, XML ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ํŒŒ์‹ฑํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ Android ๊ฐœ๋ฐœ์ž๋“ค์ด ๋”์šฑ ์‰ฝ๊ฒŒ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

 

Retrofit2 ๊ธฐ๋ณธ ๊ฐœ๋…

Retrofit2 ํŠน์ง•

1. ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜์˜ ์„ ์–ธ์  HTTP ํด๋ผ์ด์–ธํŠธ

  • Retrofit์€ API ์š”์ฒญ์„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ •์˜ํ•˜์—ฌ, ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์†Œ๋“œ์— ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด HTTP ๋ฉ”์†Œ๋“œ๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ์ž๋™ ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ

  • Retrofit์€ Gson, Moshi ๋“ฑ๊ณผ ๊ฐ™์€ JSON ํŒŒ์„œ์™€ ํ†ตํ•ฉ๋˜์–ด, ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์ž๋ฐ”/์ฝ”ํ‹€๋ฆฐ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

3. ๋™๊ธฐ ๋ฐ ๋น„๋™๊ธฐ ํ˜ธ์ถœ ์ง€์›

  • Retrofit์€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ UI ์“ฐ๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ๋„คํŠธ์›Œํฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ํ”Œ๋Ÿฌ๊ทธ๋ธ” ์•„ํ‚คํ…์ฒ˜

  • Interceptors, Converters, CallAdapters์™€ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐฉ์‹์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ๋‹ค.

5. RxJava์™€์˜ ํ†ตํ•ฉ

  • Retrofit์€ RxJava์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉ๋˜์–ด, ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ด์šฉํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

Retrofit์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

 

  • Base URL: ๋ชจ๋“  HTTP ์š”์ฒญ์˜ ๊ธฐ๋ณธ์ด ๋˜๋Š” URL.
  • Converter: JSON๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์—ญํ• . ๊ธฐ๋ณธ์ ์œผ๋กœ Gson์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ํ•„์š”์— ๋”ฐ๋ผ Moshi๋‚˜ ๋‹ค๋ฅธ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Call: API ์š”์ฒญ์„ ์ถ”์ƒํ™”ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ, Call ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • Annotations: HTTP ๋ฉ”์†Œ๋“œ์™€ ์—”๋“œํฌ์ธํŠธ, ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ๋“ฑ์„ ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์†Œ๋“œ์— ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ง€์ •ํ•œ๋‹ค.
  • Retrofit ๊ฐ์ฒด: Retrofit ์„ค์ •์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

 

Retrofit2 ์„ค์น˜

Retrofit2๋ฅผ Android ํ”„๋กœ์ ํŠธ์— ์„ค์น˜ํ•˜๋ ค๋ฉด 'build.gradle'ํŒŒ์ผ์— ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅด ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

Gradle ์„ค์ •

1. ํ”„๋กœ์ ํŠธ์˜ 'build.gradle'ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ข…์†์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'      // Retrofit ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // Gson ์ปจ๋ฒ„ํ„ฐ
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1' // ๋กœ๊ทธ ์ธํ„ฐ์…‰ํ„ฐ (์„ ํƒ ์‚ฌํ•ญ)
}

 

2. ํ”„๋กœ์ ํŠธ๋ฅผ ์‹ฑํฌํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์ ์šฉํ•œ๋‹ค.

 

Retrofit2 ์‚ฌ์šฉ๋ฒ•

1.Retrofit ์„ค์ •

Retrofit์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € Retrofit ๊ฐ์ฒด๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋Š” HTTP ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , API ์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    private static final String BASE_URL = "https://api.example.com/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create()) // Gson ์ปจ๋ฒ„ํ„ฐ ์„ค์ •
                    .build();
        }
        return retrofit;
    }
}

 

2. API ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜

Retrofit์€ API ์š”์ฒญ์„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ •์˜ํ•œ๋‹ค. ๊ฐ API ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•ด ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์†Œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด HTTP ๋ฉ”์†Œ๋“œ ๋ฐ URL ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;

public interface ApiService {
    // GET ์š”์ฒญ: ์‚ฌ์šฉ์ž ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
    @GET("users")
    Call<List<User>> getUsers();

    // GET ์š”์ฒญ: ํŠน์ • ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
    @GET("users/{id}")
    Call<User> getUserById(@Path("id") int userId);
}

 

๋”๋ณด๊ธฐ

์ฝ”ํ‹€๋ฆฐ ์˜ˆ์ œ

import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.Path

interface ApiService {

    // ๋™์ ์œผ๋กœ Authorization ํ—ค๋” ์ถ”๊ฐ€
    @GET("users/{id}")
    fun getUserById(@Path("id") userId: Int, @Header("Authorization") token: String): Call<User>

    // ๊ณ ์ •๋œ ํ—ค๋” ์ถ”๊ฐ€
    @Headers("Content-Type: application/json")
    @GET("users/{id}")
    fun getUserByIdWithHeaders(@Path("id") userId: Int): Call<User>
}

 

3. ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์ •์˜

์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›๋Š” JSON ๋ฐ์ดํ„ฐ๋ฅผ ๋งคํ•‘ํ•  ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•œ๋‹ค. Gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋ฐ” ๊ฐ์ฒด(์ฝ”ํ‹€๋ฆฐ์€ ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค)๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

public class User {
    private int id;
    private String name;
    private String email;

    // Getter ๋ฐ Setter ๋ฉ”์†Œ๋“œ
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

 

๋”๋ณด๊ธฐ

์ฝ”ํ‹€๋ฆฐ ์˜ˆ์ œ

data class User(
    val id: Int,
    val name: String,
    val email: String
)

 

4. ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹คํ–‰

Retrofi ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด API ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Retrofit ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ API ์„œ๋น„์Šค ์ดˆ๊ธฐํ™”
        Retrofit retrofit = ApiClient.getClient();
        ApiService apiService = retrofit.create(ApiService.class);

        // ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์š”์ฒญ
        Call<List<User>> call = apiService.getUsers();

        // ๋น„๋™๊ธฐ ์š”์ฒญ ์‹คํ–‰
        call.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                if (response.isSuccessful()) {
                    // ์š”์ฒญ ์„ฑ๊ณต
                    List<User> users = response.body();
                    // ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์ฒ˜๋ฆฌ
                    for (User user : users) {
                        Log.d("MainActivity", "User ID: " + user.getId());
                        Log.d("MainActivity", "User Name: " + user.getName());
                        Log.d("MainActivity", "User Email: " + user.getEmail());
                    }
                } else {
                    // ์š”์ฒญ ์‹คํŒจ (์ƒํƒœ ์ฝ”๋“œ)
                    Log.e("MainActivity", "Request Failed. Code: " + response.code());
                }
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
                // ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜
                Log.e("MainActivity", "Network Error: " + t.getMessage());
            }
        });
    }
}

 

๋”๋ณด๊ธฐ

์ฝ”ํ‹€๋ฆฐ ์˜ˆ์ œ

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

fun main() {
    val apiService = ApiClient.getClient().create(ApiService::class.java)

    // ๋™์  ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ
    val call: Call<User> = apiService.getUserById(1, "Bearer YOUR_TOKEN_HERE")
    call.enqueue(object : Callback<User> {
        override fun onResponse(call: Call<User>, response: Response<User>) {
            if (response.isSuccessful) {
                val user = response.body()
                // ์‚ฌ์šฉ์ž ์ •๋ณด ์ฒ˜๋ฆฌ
                println("User: $user")
            } else {
                println("Request failed with code: ${response.code()}")
            }
        }

        override fun onFailure(call: Call<User>, t: Throwable) {
            // ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
            println("Request failed with error: ${t.message}")
        }
    })
}

 

์„ค๋ช…

  • enqueue(object : Callback<User>): Retrofit2์˜ ๋น„๋™๊ธฐ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ฝœ๋ฐฑ์„ ์ œ๊ณตํ•œ๋‹ค.

 

Retrofit2์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

1. HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ

Retrofit2๋Š” ๋‹ค์–‘ํ•œ HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ๊ฐ ๋ฉ”์†Œ๋“œ๋ฅผ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ ์–ธํ•œ๋‹ค.

 

  • @GET: GET ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • @POST: POST ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • @PUT: PUT ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • @DELETE: DELETE ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • @PATCH: PATCH ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

์˜ˆ์‹œ : ๋‹ค์–‘ํ•œ HTTP ๋ฉ”์†Œ๋“œ

public interface ApiService {
    // POST ์š”์ฒญ: ์ƒˆ ์‚ฌ์šฉ์ž ์ƒ์„ฑ
    @POST("users")
    Call<User> createUser(@Body User user);

    // PUT ์š”์ฒญ: ์‚ฌ์šฉ์ž ์ •๋ณด ์—…๋ฐ์ดํŠธ
    @PUT("users/{id}")
    Call<User> updateUser(@Path("id") int userId, @Body User user);

    // DELETE ์š”์ฒญ: ์‚ฌ์šฉ์ž ์‚ญ์ œ
    @DELETE("users/{id}")
    Call<Void> deleteUser(@Path("id") int userId);
}

 

 

2. ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ

  • ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ: URL ๊ฒฝ๋กœ์˜ ์ผ๋ถ€๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜์ด๋‹ค. @Path ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ: URL ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ณ€์ˆ˜์ด๋‹ค. @Query ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.

์˜ˆ์‹œ : ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ

public interface ApiService {
    // ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ
    @GET("users/{id}")
    Call<User> getUserById(@Path("id") int userId);

    // ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ
    @GET("users")
    Call<List<User>> getUsersByAge(@Query("age") int age);
}

 

 

3. ์š”์ฒญ ๋ณธ๋ฌธ Request Body

POST, PUT ์š”์ฒญ์—์„œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด '@Body' ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ณธ๋ฌธ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ : ์š”์ฒญ ๋ณธ๋ฌธ

public interface ApiService {
    // POST ์š”์ฒญ: ์ƒˆ ์‚ฌ์šฉ์ž ์ƒ์„ฑ
    @POST("users")
    Call<User> createUser(@Body User user);
}

 

4. ํ—ค๋” Headers

API ์š”์ฒญ ์‹œ ํŠน์ • ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, '@Header' ๋˜๋Š” '@Headers' ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด HTTP ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ : ํ—ค๋” ์„ค์ •

public interface ApiService {
    // ๋‹จ์ผ ํ—ค๋” ์„ค์ •
    @GET("users")
    Call<List<User>> getUsers(@Header("Authorization") String token);

    // ๋ณต์ˆ˜ ํ—ค๋” ์„ค์ •
    @Headers({
        "Accept: application/json",
        "User-Agent: Retrofit-Sample-App"
    })
    @GET("users")
    Call<List<User>> getUsersWithHeaders();
}

 

 

5. Interceptors

Interceptros๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋ฐ ์‘๋‹ต์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ธ์ฆ ํ† ํฐ์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋””๋ฒ„๊น… ์‹œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ/์‘๋‹ต์„ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์˜ˆ์‹œ : Interceptor ์‚ฌ์šฉ

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;

public class ApiClient {
    private static final String BASE_URL = "https://api.example.com/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit == null) {
            // Interceptor ์„ค์ •
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(new Interceptor() {
                        @Override
                        public Response intercept(Chain chain) throws IOException {
                            Request original = chain.request();
                            Request request = original.newBuilder()
                                    .header("Authorization", "Bearer YOUR_TOKEN_HERE")
                                    .method(original.method(), original.body())
                                    .build();
                            return chain.proceed(request);
                        }
                    })
                    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) // ๋กœ๊ทธ ์ถœ๋ ฅ
                    .build();

            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

 

Retrofit2์™€ RxJava ํ†ตํ•ฉ

Retrofit2๋Š” RxJava์™€ ํ†ตํ•ฉ๋˜์–ด ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ†ตํ•ด ๋น„๋™๊ธฐ ์š”์ฒญ์„ ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Gradle ์„ค์ •

RxJava์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถ”๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

dependencies {
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
}

 

RxJava๋ฅผ ํ™œ์šฉํ•œ Retrofit ์˜ˆ์ œ

import io.reactivex.Observable;
import retrofit2.http.GET;

public interface ApiService {
    // RxJava Observable๋กœ ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์š”์ฒญ
    @GET("users")
    Observable<List<User>> getUsers();
}

// Retrofit ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ RxJava Adapter ์ถ”๊ฐ€
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava ์–ด๋Œ‘ํ„ฐ ์ถ”๊ฐ€
        .build();

ApiService apiService = retrofit.create(ApiService.class);

// RxJava Observable ๊ตฌ๋… ๋ฐ ์ฒ˜๋ฆฌ
apiService.getUsers()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(users -> {
        // ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์ฒ˜๋ฆฌ
    }, throwable -> {
        // ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
    });

 

๊ฒฐ๋ก 

Retrofit2๋Š” Android ๊ฐœ๋ฐœ์—์„œ RESTful API์™€์˜ ํ†ต์‹ ์„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฐ•๋ ฅํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‹ค. Retrofit์˜ ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜ ์„ ์–ธ, ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜, ๋น„๋™๊ธฐ ์š”์ฒญ ์ง€์› ๋“ฑ์˜ ๊ธฐ๋Šฅ์€ RESTful API ํ†ตํ•ฉ์„ ๋‹จ์ˆœํ™”ํ•˜๊ณ , ๊ฐœ๋ฐœ์ž์˜ ์ƒ์‚ฐ์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.

Retrofit2๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , RxJava์™€์˜ ํ†ตํ•ฉ์„ ํ†ตํ•ด ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋”์šฑ ๋น ๋ฅด๊ณ  ์•ˆ์ •์ ์ธ Android ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค.

 


๊ด€๋ จ ๊ธ€