Retrofit2를 이용한 REST API 통신

김남주 - 2024년 05월 27일

java retrofit2 REST API

Retrofit2를 이용한 REST API 통신

Retrofit2란?

Retrofit2는 안드로이드에서 네트워크 통신을 위한 라이브러리로, REST API 통신을 쉽게 구현할 수 있도록 도와줍니다.

Retrofit2의 장점

  1. 간단한 인터페이스 정의 : REST API 통신을 위한 인터페이스를 정의하면, Retrofit2가 이를 구현해줍니다.
  2. 동기/비동기 호출 지원 : 동기/비동기 호출을 지원하여, 편리하게 사용할 수 있습니다.
  3. JSON/XML 파싱 지원 : JSON 또는 XML 형식의 데이터를 쉽게 파싱할 수 있습니다.
  4. 캐싱 지원 : 캐싱을 지원하여, 네트워크 통신을 최소화할 수 있습니다.

Retrofit2 사용 방법

  1. Gradle에 의존성 추가

    dependencies {
        // Retrofit
        implementation 'com.squareup.retrofit2:retrofit:2.11.0'
        implementation 'com.squareup.retrofit2:converter-gson:2.11.0'
    
        // OkHttp
        implementation 'com.squareup.okhttp3:okhttp:4.12.0'
        implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
    
        // Logging
        implementation 'ch.qos.logback:logback-classic:1.5.6'
        implementation 'ch.qos.logback:logback-core:1.5.6'
        implementation 'org.slf4j:slf4j-api:2.1.0-alpha1'
    }
    
  2. DTO(Data Transfer Object) 클래스 생성

    API 통신을 위한 데이터 클래스를 생성합니다.

    예를들어 JSONPlaceholder에서 제공하는 Post API를 사용한다고 가정해보겠습니다.

    {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    }
    

    다음과 같이 Json 형식의 데이터를 전달받을수 있는데, 이를 Json to Java같은 서비스를 이용하여 편리하게 DTO 클래스를 생성할 수 있습니다.

    손으로 직접 타이핑하는것도 좋지만, 이런 도구를 사용하면 오타의 위험을 줄일 수 있습니다.

    사용 예시 : Post DTO 클래스 Json to Java

    package org.example.dto;
    
    import lombok.Builder;
    import lombok.Data;
    
    @Data
    @Builder
    public class Post {
        private int userId;
        private int id;
        private String title;
        private String body;
    }
    
  3. Retrofit2 인터페이스 생성

    Retrofit2를 사용하기 위해 API 통신을 위한 인터페이스를 생성합니다.

    @GET, @POST, @PUT, @DELETE 등의 어노테이션을 사용하여 HTTP Method를 지정할 수 있습니다.

    @Path, @Query, @Body 등의 어노테이션을 사용하여 URL Path, Query Parameter, Request Body 등을 지정할 수 있습니다.

    여기서 Call 객체를 반환하는데, 이 객체를 통해 비동기/동기 호출을 수행할 수 있습니다.

    따라서 비동기 호출을 수행할 때에는 enqueue 메서드를 사용하고, 동기 호출을 수행할 때에는 execute 메서드를 사용합니다.

    package org.example.retrofit;
    
    import org.example.dto.Post;
    import retrofit2.Call;
    import retrofit2.http.*;
    
    import java.util.List;
    
    public interface PostRepository {
    
        @GET("/posts")
        Call<List<Post>> getPosts();
    
        @GET("/posts/{id}")
        Call<Post> getPostById(
                @Path("id") int id
        );
    
        @POST("/posts")
        Call<Post> createPost(
                @Body Post post
        );
    
        @PUT("/posts/{id}")
        Call<Post> updatePost(
                @Path("id") int id,
                @Body Post post
        );
    
        @DELETE("/posts/{id}")
        Call<Void> deletePost(
                @Path("id") int id
        );
    }
    
  4. Retrofit2 객체 생성

    Retrofit2 객체를 생성하고, 인터페이스를 구현한 객체를 생성합니다.

    객체를 생성할 때 baseUrlConverter를 지정해줍니다.

    • baseUrl : API의 기본 URL을 지정합니다.
    • Converter : JSON, XML 등의 데이터를 변환할 Converter를 지정합니다. 여기서는 GsonConverterFactory를 사용합니다.
      • 객체를 Json으로 변환하거나, Json을 객체로 변환하는데 사용됩니다.
    package org.example.retrofit;
    
    import lombok.Getter;
    import retrofit2.Retrofit;
    import retrofit2.converter.gson.GsonConverterFactory;
    
    public class RetrofitImpl {
    
        static final String BASE_URL = "https://jsonplaceholder.typicode.com";
    
        // RetrofitImpl 클래스의 메서드
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    
        @Getter
        PostRepository postRepository = retrofit.create(PostRepository.class);
    }
    
  5. Retrofit2 사용

    Retrofit2 객체를 생성하고, API 통신을 수행합니다.

    Reetrofit 객체의 경우 실제로 개발을 할 때에는 싱글톤 패턴을 사용하여 객체를 생성하는 것이 좋습니다.

    Android Dagger를 이용하거나, Kotlin 의 Object 키워드를 사용하여 싱글톤 객체를 생성할 수 있습니다.

    함수를 호출할 때에는 enqueue 또는 execute 메서드를 사용하여 비동기/동기 호출을 수행할 수 있습니다.

    enqueue 메서드의 경우 Callback 객체를 전달하여 비동기 호출 결과를 처리할 수 있습니다. 다음과 같이 onResponseonFailure 메서드를 구현하여 성공/실패 시 처리를 할 수 있습니다.

    @Slf4j
    public class Main {
        public static void main(String[] args) throws IOException {
    
            RetrofitImpl retrofit = new RetrofitImpl();
            PostRepository postRepository = retrofit.getPostRepository();
            CommentRepository commentRepository = retrofit.getCommentRepository();
    
    
            // 게시글 1개 조회 - 동기
            postRepository.getPostById(1).execute();
    
            // 게시글 1개 댓글 조회 - 비동기
            commentRepository.getCommentsByPostId(1).enqueue(
                    new Callback<List<Comment>>() {
                        @Override
                        public void onResponse(Call<List<Comment>> call, Response<List<Comment>> response) {
                            if (response.isSuccessful() && response.body() != null) {
                                List<Comment> comments = response.body();
                                comments.forEach(comment -> log.info(comment.toString()));
                            } else {
                                log.error("Fail to get comments");
                            }
                        }
    
                        @Override
                        public void onFailure(Call<List<Comment>> call, Throwable t) {
                            log.error("Fail to get comments", t);
                        }
                    }
            );
    
        }
    }
    

    실행 결과

    SLF4J(I): Connected with provider of type [ch.qos.logback.classic.spi.LogbackServiceProvider]
    12:44:18.069 [OkHttp https://jsonplaceholder.typicode.com/...] INFO org.example.Main -- Comment(postId=1, id=1, name=id labore ex et quam laborum, email=Eliseo@gardner.biz, body=laudantium enim quasi est quidem magnam voluptate ipsam eos
    tempora quo necessitatibus
    dolor quam autem quasi
    reiciendis et nam sapiente accusantium)
    12:44:18.072 [OkHttp https://jsonplaceholder.typicode.com/...] INFO org.example.Main -- Comment(postId=1, id=2, name=quo vero reiciendis velit similique earum, email=Jayne_Kuhic@sydney.com, body=est natus enim nihil est dolore omnis voluptatem numquam
    et omnis occaecati quod ullam at
    voluptatem error expedita pariatur
    nihil sint nostrum voluptatem reiciendis et)
    12:44:18.072 [OkHttp https://jsonplaceholder.typicode.com/...] INFO org.example.Main -- Comment(postId=1, id=3, name=odio adipisci rerum aut animi, email=Nikita@garfield.biz, body=quia molestiae reprehenderit quasi aspernatur
    aut expedita occaecati aliquam eveniet laudantium
    omnis quibusdam delectus saepe quia accusamus maiores nam est
    cum et ducimus et vero voluptates excepturi deleniti ratione)
    12:44:18.072 [OkHttp https://jsonplaceholder.typicode.com/...] INFO org.example.Main -- Comment(postId=1, id=4, name=alias odio sit, email=Lew@alysha.tv, body=non et atque
    occaecati deserunt quas accusantium unde odit nobis qui voluptatem
    quia voluptas consequuntur itaque dolor
    et qui rerum deleniti ut occaecati)
    12:44:18.072 [OkHttp https://jsonplaceholder.typicode.com/...] INFO org.example.Main -- Comment(postId=1, id=5, name=vero eaque aliquid doloribus et culpa, email=Hayden@althea.biz, body=harum non quasi et ratione
    tempore iure ex voluptates in ratione
    harum architecto fugit inventore cupiditate
    voluptates magni quo et)
    

결론

Retrofit2를 사용하면, 간단한 인터페이스 정의와 동기/비동기 호출 지원으로 REST API 통신을 쉽게 구현할 수 있습니다.

또한, JSON/XML 파싱 지원과 캐싱 지원으로 데이터를 쉽게 처리할 수 있습니다.

Java환경에서 REST API 통신을 구현할 때에는 Retrofit2를 사용하여 편리하게 개발할 수 있습니다.