티스토리 뷰
이전 글에 이어서 서버에서 HTTP 요청을 하는 방법에 대한 정리 글이다.
이전 글에선 JAVA에서 사용되는 API를 살펴봤다면, 이번에는 Spring에서 제공하는 방식에 대해 알아보려 한다.
Spring Framework 에서는 HTTP 요청을 위해 대표적으로 세 가지 API를 지원한다.
RestTemplate
Spring 3부터 지원, 전통적인 blocking/동기식 HTTP request 기능 제공
AsyncRestTemplate
Spring 4에 추가된 RestTemplate에 비동기 기능을 추가한 방식
WebClient
Spring 5에 추가된 RestTemplate을 보완하기 위한 HTTP requests non-blocking/reactive 클라이언트
크게 RestTemplate/WebClient로 분류해 정리해보려고 한다.
1. RestTemplate
RestTemplate은 Spring Framework에서 RESTful HTTP 요청을 위해 제공하는 클래스다.
이전 글에서 알아봤던 HttpURLConnection, Apache HttpClient 보다 추상화되어 더 직관적으로 구현이 가능하다.
이 외에도 Request 및 Reponse를 자동으로 직렬화 및 역직렬화하여 HTTP를 통해 주고받을 수 있으며, 다양한 데이터 유형을 지원해 JSON, XML 및 HTML과 같은 Request 및 Reponse를 작성 할 수 있다.
검색해보면 동작방식에 대한 이야기도 있지만 해당 내용은 생략하겠음..
1.1 APIs
REST API의 리소스와 정보를 주고 받기 위해, 총 41가지 매서드가 제공 된다. 하지만 41개의 전체 매서드의 대부분은 12개의 매서드를 기준으로 오버로드되었다.
Operation | 매서드 | 동작 |
DELETE | delete() | 지정된 URL에 HTTP DELETE 요청을 처리 |
GET | getForEntity() getForObject() |
GET 방식으로 요청해, Response에서 매핑된 Object가 포함된 ResponseEntity를 반환 GET 방식으로 요청해, Response에서 매핑된 Object를 반환 |
POST | postForEntity() postForLocation() postForObject() |
POST 방식으로 요청해, Reponse에서 매핑된 Object가 포함된 Entity를 반환 POST 방식으로 요청해, 새로 생성된 리소스의 URL을 반환 POST 방식으로 요청해, Reponse에서 매핑된 Object를 반환 |
PUT | put() | 지정된 URL에 HTTP PUT 요청을 처리 |
PATCH | patchForObject() | PATCH 방식으로 요청해, Reponse에서 매핑된 Object를 반환 |
HEAD | headForHeaders() | 지정한 리소스 URL에 대한 HTTP 헤더를 반환하는 HTTP HEAD 요청 |
ANY | exchange() execute() |
URL에 대해 지정된 HTTP 메서드를 실행하여 Object가 포함된 ResponseEntity를 반환. URL에 대해 지정된 HTTP 메서드를 실행하여 응답 본문에서 매핑된 Object를 반환. |
1.2 구현
이전과 같이 GET 방식과 POST 방식만 정리
1.2.1 GET 방식
Reponse를 일반 Object와 ResponseEntity로 받는 방법이 있다.
RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/users/{id}";
Map<String, String> params = new HashMap<>();
params.put("id", "123");
User user = restTemplate.getForObject(url, User.class, params);
위와 같이 작성하면 http://example.com/users/123 URL로 Request를 보내 User 객체를 Response로 받는다. Reponse를 ResponseEntity 형식으로 받을 수도 있다.
ResponseEntity<User> response = restTemplate.getForEntity(url, User.class, params);
1.2.2 POST 방식
GET 방식과 유사하다.
RestTemplate restTemplate = new RestTemplate();
String url = "http://example.com/users";
User user = new User();
user.setName("John");
user.setAge(30);
User createdUser = restTemplate.postForObject(url, user, User.class);
위와 같이 작성하면 http://example.com/users URL로 Request를 보내 User 객체를 Response로 받는다.
POST 방식도 GET 방식과 유사하게 Reponse를 ResponseEntity 형식으로 받을 수 있다.
ResponseEntity<User> response = restTemplate.postForEntity(url, user, User.class);
사용법이 한눈에 들어올 정도로 추상화가 잘 되어 있는 것을 확인할 수 있다. 예제로는 작성하지 않았지만 REST API의 다른 method들도 구현되어 있다. Docs에서 확인할 수 있다.
1.3 단점
앞서 이야기했지만 RestTemplate의 가장 큰 문제는 blocking, 동기식으로만 동작한다는 점이다.
때문에 서비스 로직이 굉장히 복잡하거나 오래 걸릴 경우, 쓰레드 차단으로 인해 지연이 발생할 수 있다.
RestTemplate은 다른 HTTP 클라이언트 라이브러리만큼 자유롭게 사용하기가 어렵다.
예를 들어, 자세하게 요청의 HTTP 헤더 또는 요청 매개 변수를 사용자 지정하는 방법을 제공하지 않거나 설정 방법이 복잡하다.
2. WebClient
Spring에서 제공하는 HTTP 요청을 만들기 위한 reactive, non-blocking client다. 스프링 프레임워크의 WebFlux 모듈에 포함되어 있다.
RestTemplate의 블로킹 및 동기식과 달리 WebClient는 싱글 쓰레드에서 동작하는 논블로킹 및 반응형이라 여러 요청을 동시에 수행하고 응답을 비동기식으로 처리할 수 있다.
RestTemplate 클래스의 대안으로 사용하도록 설계되었으며,
WebClient가 등장한 Spring 5부터는 deprecated 되어 더 이상 추가개발/관리를 하지 않을 것이기 때문에 RestTemplate 대신 WebClient를 사용하도록 권장하고 있다.
2.1 구성
WebClient를 만드는 가장 간단한 방법은 정적 팩터리 메서드 중 하나 를 사용하는 것이다.
WebClient.create()
WebClient.create(String baseUrl)
WebClient.builder()의 추가 옵션을 지정할 수 있다.
uriBuilderFactoryUriBuilderFactory: 기본 URL로 사용하도록 맞춤
defaultUriVariables: URI 템플릿을 확장할 때 사용할 기본값
defaultHeader: 모든 요청에 대한 헤더
defaultCookie: 모든 요청에 대한 쿠키.
defaultRequest: 모든 요청에 Consumer를 지정합니다.
filter: 모든 요청에 대한 클라이언트 필터.
exchangeStrategies: HTTP 메시지 판독기/작성기 사용자 정의.
clientConnector: HTTP 클라이언트 라이브러리 설정.
2.2 구현
이번에도 GET 방식과 POST 방식만 정리
2.2.1 GET 방식
WebClient client = WebClient.create();
Mono<String> response = client.get().uri("http://example.com/users/{id}", 123)
.retrieve()
.bodyToMono(String.class);
http://example.com/users/123 으로 요청해 String 방식으로 Response를 받는다.
2.2.2 POST 방식
WebClient client = WebClient.create();
Mono<String> response = client.post().uri("http://example.com/users")
.bodyValue(new User("John", 30))
.retrieve()
.bodyToMono(String.class);
http://example.com/users 로 요청해 역시 String 방식으로 Response를 받는다.
RestTempalte 방식만큼이나 직관적이고, Builder 패턴을 제공해 객체 생성이 더 용이하다는 장점이 있다.
또 Flux 객체를 받아서 처리 할 수도 있다. bodyToMono를 bodyToFlux로 변경.
Flux<Person> people = request.bodyToFlux(Person.class);
다만, 몇 가지 단점도 있다. WebFlux 모듈을 쓰기 때문에 스프링 버전이 낮은 경우 WebClient를 사용할 수 없다는 것과 Response를 위해 별도의 구현이 필요하다는 점이다.
3. 마치며
자바/Spring에서 HTTP 요청을 보내는 방식을 알아보았다. 최종적으론 WebClient를 사용하는 것을 권장하기 때문에 WebFlux를 추가적으로 알아봐야할 것 같다.
'개발 > SPRING' 카테고리의 다른 글
스프링 부트에서 캐시(Cache) 초간단 사용하기 (0) | 2023.04.26 |
---|---|
RestTemplate의 올바른 사용방법 (0) | 2023.03.25 |
[Spring] Filter, Interceptor, AOP (0) | 2023.01.21 |
[Spring] DispatcherServlet (0) | 2023.01.21 |
[Spring] Exception 처리, ControllerAdvice (0) | 2023.01.06 |
- Total
- Today
- Yesterday
- MySQL
- openAI API
- 람다
- AOP
- CloudFront
- elasticsearch
- springboot
- OpenAI
- S3
- lambda
- serverless
- 티스토리챌린지
- Log
- terraform
- AWS
- 스프링부트
- JWT
- Kotlin
- 후쿠오카
- OpenFeign
- ChatGPT
- EKS
- Elastic cloud
- GIT
- 오블완
- AWS EC2
- java
- Spring
- docker
- cache
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |