모르지 않다는 것은 아는것과 다르다.

Spring Cloud

Retrofit

채마스 2022. 4. 9. 12:22

Retrofit 란?

  • Retrofit 은 Java 에서 REST Client 를 간편하게 구현할 수 있도록 기능을 제공하는 라이브러리이다.
  • Spring Web 에서 제공하는 RestTemplate 도 이와 동일한 기능을 제공하지만, Retrofit 을 사용할 때가 코드 가독성과 편의성이 좀더 높다.
  • Retrofit 은 Annotation 과 Interface 로 선언된 HTTP API 명세를 기반으로 HTTP API 구현체를 생성해준다.
  • Retrofit 은 HTTP API 의 요청과 응답에서 타입을 강제하여 Type Safe 한 장점을 제공한다.
  • 타입이 강제되기 때문에 개발 과정에서 요청과 응답에 대한 예측이 가능하다.

 

의존성 추가

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
  • 위와 같이 의존성을 추가해준다.

 

구현

HTTP API interface 선언

public interface RetrofitApiTest {

    @GET("api/sr/retrofit-test")
    Call<APIDataResponse<String>> test();
}
  • HTTP Method - @GET, @POST, @PUT, @DELETE 를 제공한다.
  • Request Body 를 표현하는 @Body 를 제공한다.
  • Form-encoded 를 표현하는 @FormUrlEncoded 를 제공한다.
  • MultiPart 를 표현하는 @Part 를 제공한다.
  • Path Variable 을 표현하는 @Path 를 제공한다.
  • Query Parameter 을 표현하는 @Query 를 제공한다.
  • 요청 Header 를 표현하는 @Headers 또는 @Header 를 제공한다.

Builder 구현

public static Retrofit initRetrofit(String baseUrl) {
    return new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(httpClient.build())
            .build();
}
  • HTTP 통신에 대한 baseUrl 과 converter 등을 설정한다.
  • 선언된 HTTP API Interface 를 생성하는 Retrofit 객체를 생성한다.
  • hrrtClient 선언 시 Connection Timeout, ReadTimeout 설정이 가능하고, HTTP 요청과 응답에 대한 로깅을 남기는 Interceptor 선언도 가능하다.

Retrofit.create()

@Bean
public RetrofitApiTest retrofitOrderApi() {
    var retrofit = RetrofitUtils.initRetrofit(baseUrl);
    return retrofit.create(RetrofitApiTest.class);
}
  • Retrofit.create() 메소드를 활용하여 사전에 선언한 HTTP API Interface 의 실제 구현체를 생성하고 사용한다.

 

RetrofitUtils 전체 코드

public class RetrofitUtils {
    private static final HttpLoggingInterceptor loggingInterceptor
            = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);

    private static final OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .connectTimeout(3, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS);

    private static final Gson gson = new GsonBuilder()
            .setLenient()
            .create();

    public static Retrofit initRetrofit(String baseUrl) {
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(httpClient.build())
                .build();
    }

    public <T extends APIDataResponse> Optional<T> responseSync(Call<T> call) {
        try {
            Response<T> execute = call.execute();
            if (execute.isSuccessful()) {
                return Optional.ofNullable(execute.body());
            } else {
                log.error("requestSync errorBody = {}", execute.errorBody());
                throw new RuntimeException("retrofit execute response error");
            }
        } catch (IOException e) {
            log.error("", e);
            throw new RuntimeException("retrofit execute IOException");
        }
    }

    public void responseVoid(Call<Void> call) {
        try {
            if (!call.execute().isSuccessful()) throw new RuntimeException();
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
}
  • 위와 같이 로깅을 위한 인터셉터와 httpClient 설정을 해준다.
  • responseSync 메소드의 결과 값으로 직접 커스텀한 APIDataResponse 를 넘겨준다.
  • 실제로 responseSync 메소드가 호출 되는 시점에 REST Client 요청이 호출된다.




REFERENCES

  • 이희창님의 Java/Spring 기반 서비스 개발

'Spring Cloud' 카테고리의 다른 글

MDC (Mapped Diagnostic Context)  (0) 2022.02.28