Spring) WebClient 사용해서 외부 서버 API 요청하기 & 응답 받기(동기식)

오성민·2023년 1월 13일
1

spring

목록 보기
12/17
post-thumbnail

Spring Boot 환경에서 OAuth2 Login을 적용하려고 하면서 1가지의 문제점이 생겼다.
평소에 서버에서는 API를 받을 준비를 하고 응답을 구성하기만 하고, 요청과 응답을 받는 것은 클라이언트에서만 해봤었다.
서버에서 인가 코드를 활용해서 토큰을 요청해야한다.
그래서 spring에서 다른 REST API 를 요청하고 응답 받는 방법을 정리하고, 내가 실제로 했던 방법들을 정리하려고 한다.

요청 방법

1. RestTemplate

두괄식으로 얘기하면 이 방법을 사용하면 안된다.
이 방법은 점점 더 사용되지 않는 방법이라고 한다. 그리고 필자는 구글링을 하면서 사용을 해보려고 했는데 dependency를 추가해줘도 계속해서 ClassNotFound라고 HttpClient라는 class를 찾을 수 없다는 예외가 계속해서 발생을 했다.
그래서 이 방법이 아닌 다음 방법을 정리하려고 한다.

2. WebClient

spring framwork에서 사용하는 api 요청 라이브러리이다. 해당 라이브러리는 동기 및 비동기 통신이 가능하다. 이것이 매우 큰 장점이다.

dependency(gradle)

// webclient
implementation 'org.springframework.boot:spring-boot-starter-webflux'

위와 같은 의존성을 추가해주면 사용을 할 수 있다.

객체 생성법

사용법은 크게 2가지로 나뉘어있다.

1. 사용할 때 객체 생성

사용할 때 바로 객체를 생성해서 사용을 하는 방법이다.

WebClient client = WebClient.builder()
                .defaultHeader("Content-type" , "application/x-www-form-urlencoded;charset=utf-8")
                .baseUrl(kakaoUri)
                .build();

여기에서 굉장히 큰 장점이 나오는데 WebClient는 여러 가지 설정을 하기 편하게 builder를 지원한다.
그래서 필자는 Kakao OAuth2 Login 스펙에 맞게 헤더에 content-type을 설정해주었다.
그리고 baseUrl에 이름 그대로 base url을 넣어주면 된다.

위 방법이 어렵다하면 간단하게
WebClient.create(${baseUrl})
을 사용할 수도 있다.

2. @Bean으로 등록

자주 사용하는 url은 bean으로 등록할 수도 있다.

API 요청 방법

요청하는 방법에는 동기식과 비동기식이 있다.

동기식

JSONObject results = client.post()//client <- 위에서 만든 객체
                .uri("/oauth/token")//base 뒤에 붙은 uri
                .accept(MediaType.APPLICATION_JSON)//어떤 타입을 허락할지
                .body(BodyInserters.fromValue(body))//만든 body를 넣어줌
                .retrieve()//받은 데이터를 디코딩 해줌
                .bodyToMono(JSONObject.class)//어떤 타입으로 디코딩할 것인지
                .block();//동기식

동기식은 위와 같은 방법을 사용한다.
위 코드를 보면 WebClient가 얼마나 자세하게 설정을 할 수 있는지 나온다.

client.${ 어떤 요청을 보낼 것인지 }
만약 get이라면 get()을 patch라면 patch()를 사용해서 요청을 보내면 된다.

비동기식

비동기식은 동기식과 동일하지만 다른 점이 2가지가 존재한다.

Mono<JSONObject> results = client.post()//client <- 위에서 만든 객체
                .uri("/oauth/token")//base 뒤에 붙은 uri
                .accept(MediaType.APPLICATION_JSON)//어떤 타입을 허락할지
                .body(BodyInserters.fromValue(body))//만든 body를 넣어줌
                .retrieve()//받은 데이터를 디코딩 해줌
                .bodyToMono(JSONObject.class)//어떤 타입으로 디코딩할 것인지
                .subscribe();//비동기식

return type을 mono 혹은 flux로 바꾸어주면 된다.
나머지 부분은 다 똑같다.
하지만 비동기식은 아직 사용해보지 않아서 subscribe 메소드를 어떻게 사용하는지는 이해하지 못했다.

다음에 내용을 확인하고 작성하도록 해야겠다.

profile
풀스택을 지향하는 개발자

0개의 댓글