김남주 - 2024년 05월 27일
java retrofit2 REST APIRetrofit2를 이용한 REST API 통신
Retrofit2란?
Retrofit2는 안드로이드에서 네트워크 통신을 위한 라이브러리로, REST API 통신을 쉽게 구현할 수 있도록 도와줍니다.
Retrofit2의 장점
- 간단한 인터페이스 정의 : REST API 통신을 위한 인터페이스를 정의하면, Retrofit2가 이를 구현해줍니다.
- 동기/비동기 호출 지원 : 동기/비동기 호출을 지원하여, 편리하게 사용할 수 있습니다.
- JSON/XML 파싱 지원 : JSON 또는 XML 형식의 데이터를 쉽게 파싱할 수 있습니다.
- 캐싱 지원 : 캐싱을 지원하여, 네트워크 통신을 최소화할 수 있습니다.
Retrofit2 사용 방법
-
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' }
-
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 클래스
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; }
-
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 ); }
-
Retrofit2 객체 생성
Retrofit2 객체를 생성하고, 인터페이스를 구현한 객체를 생성합니다.
객체를 생성할 때
baseUrl
과Converter
를 지정해줍니다.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); }
-
Retrofit2 사용
Retrofit2 객체를 생성하고, API 통신을 수행합니다.
Reetrofit 객체의 경우 실제로 개발을 할 때에는 싱글톤 패턴을 사용하여 객체를 생성하는 것이 좋습니다.
Android Dagger를 이용하거나, Kotlin 의 Object 키워드를 사용하여 싱글톤 객체를 생성할 수 있습니다.
함수를 호출할 때에는
enqueue
또는execute
메서드를 사용하여 비동기/동기 호출을 수행할 수 있습니다.enqueue 메서드의 경우 Callback 객체를 전달하여 비동기 호출 결과를 처리할 수 있습니다. 다음과 같이
onResponse
와onFailure
메서드를 구현하여 성공/실패 시 처리를 할 수 있습니다.@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를 사용하여 편리하게 개발할 수 있습니다.