Spring WebClient

수정이·2022년 9월 30일
0

Spring

목록 보기
13/16
post-thumbnail
post-custom-banner

지난번에 파이썬 서버와 통신을 위해서 RestTemplate을 사용해 보았다.
사용을 마치고 나서 RestTemplate이 곧 deprecated 될 예정이라는 것을 알게되었다.
파이썬 서버와 새로운 통신을 할 로직을 구현할 거라 겸사겸사 리팩토링 해주기로 하였다.
이번에 쓸 방식은 Spring에서 적극 추천하는 WebClient이다.


WebClient

WebClient는 동기 API를 제공할 뿐만 아니라, 논블로킹 및 비동기 접근 방식도 지원해서 효율적인 통신이 가능하다.
그리고 외부 API로 요청을 할 때 리액티브 타입(Mono, Flux) 의 전송과 수신을 한다.

특징

  • 싱글 스레드 방식을 사용한다.
  • 논블록킹 방식을 사용한다.
  • JSON, XML을 쉽게 응답받을 수 있다.

사용 방법

지난번에 사용한 RestTemplateWebClient로 리팩토링하는 과정으로 작성하겠다.

먼저 WebClient를 사용하기 위해서는 아래와 같이 의존성을 추가해줘야한다.

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

WebClient 생성

WebClient를 생성하는 방법은 create()build()가 있다.

  • create : 디폴트 세팅으로 생성할 수 있다.
  • build : 모든 설정을 커스터마이징 할 수 있다.

헤더를 설정해줘야하기 때문에 build로 생성을 하였다.

public WebClient buildWebClient() {
        return WebClient.builder()
                .baseUrl("http://localhost:8000")
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
    }
  • baseUrl : 기본 url을 설정할 수 있다. 통신을 할 때 뒤에 api에 맞는 url만 추가해주면 된다.
  • defaultHeader : 모든 요청에 사용할 헤더를 설정할 수 있다.

POST 요청

// Http 통신 body에 들어갈 json 객체 생성
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", requestDto.getUsername());
jsonObject.put("text", requestDto.getText());
jsonObject.put("narration", "none");

// webClient를 사용하여 서버간 통신
PythonServerDto.AudioResponse responseDto = buildWebClient().post()
        .uri("/audios")
        .body(Mono.just(jsonObject.toString()), JSONObject.class)
        .retrieve()
        .bodyToMono(PythonServerDto.AudioResponse.class)
        .block();

POST 요청은 위 코드와 같이 url을 설정한 다음 body부분에 json형태의 객체를 추가해준다.
이렇게 하면 요청 코드가 완성된다. 이제 요청을 한 후에는 응답을 받아야 된다.
응답을 받을 때에는 retrieve를 사용해서 받는데 body를 받아 디코딩하는 간단한 메소드이다.

retrieve를 사용한 후에 받는 데이터의 형태를 두 가지로 나눠서 받을 수 있다.

  • toEntity() : ResponseEntity 타입으로 받는다.
  • bodyToMono(), bodyToFlux() : body의 데이터로만 받는다.

위 코드에서는 bodyToMono()로 받고 block()을 사용하여 동기로 작동하게 만들었다.


참고

ENFJ.dev

post-custom-banner

0개의 댓글