跳至主要内容

WebClient

Spring Webflux에는 reactive, non-blocking하게 HTTP요청을 처리할 수 있도록 WebClient 모듈을 제공

기존의 RestTemplate과 같은 역할이지만, non-blocking하다라는 차이가 있다.

내부적으로 WebClient는 HTTP 클라이언트 라이브러리에 위임하는데, 디폴트로 Reactor Netty의 HttpClient를 사용한다. Reactor Netty외에도, Jetty의 HttpClient를 지원하며, 다른 라이브러리도 ClientHttpConnector에 넣어주면 사용할 수 있다.


Setup the WebClient

create()

  • default WebClient
  • base URL
this.webClient = WebClient.create();
//or
this.webClient = WebClient.create("http://localhost:12345");

builder
this.webClient = WebClient.builder()
                          .baseUrl(properties.getHost())
                          .defaultHeader("Accept", MediaType.APPLICATION_JSON_VALUE,
                                         "Content-Type", MediaType.APPLICATION_JSON_VALUE
                          ).build();


Making calls

public Mono<ReturnedItem> callOne() {
    return webClient.get()
                    .uri("wait1")
                    .retrieve()
                    .bodyToMono(ReturnedItem.class);
}

public record ReturnedItem(UUID id, String info) {}
  • REST action
    • GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS의 helper method 제공됨
  • uri()
    • 호출 url, WebClient에서 설정한 baseUrl에 append 됨
  • retrieve
    • 실제 호출을 수행하고 호출을 설정하는 메서드에서 응답을 처리하는 메서드로 변환
  • bodyToMono
    • 원하는 payload를 제공

Request Body

retrieve()

response body를 가져오는 가장 단순한 방법이다. 오브젝트 stream을 Flux로 받을 수도 있다.

디폴트로, HTTP 응답 코드가 4xx, 5xx로 오면 WebClientResponseException이 발생한다. onStatus() 메소드를 통해 exception을 커스터마징할 수 있다.

Mono<Person> result = client.get()
            .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON)
            .retrieve()
            .onStatus(HttpStatus::is4xxServerError, response -> ...)
            .onStatus(HttpStatus::is5xxServerError, response -> ...)
            .bodyToMono(Person.class);

exchange()

retrieve()와 동일한 역할을 하면서 ClientResponse 객체의 접근을 가능하게 해 response 처리를 커스터마이징하기 보다 용이합니다.

Mono<Person> result = client.get()
            .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON)
            .exchange()
            .flatMap(response -> response.bodyToMono(Person.class));

Mono형태의 객체를 request body에 넣을 수 있다.

Mono<Person> personMono = ... ;

    Mono<Void> result = client.post()
            .uri("/persons/{id}", id)
            .contentType(MediaType.APPLICATION_JSON)
            .body(personMono, Person.class)
            .retrieve()
            .bodyToMono(Void.class);
Flux<Person> personFlux = ... ;

    Mono<Void> result = client.post()
            .uri("/persons/{id}", id)
            .contentType(MediaType.APPLICATION_STREAM_JSON)
            .body(personFlux, Person.class)
            .retrieve()
            .bodyToMono(Void.class);


Mono나 Flux로 감싸지 않는 실제 오브젝트는 syncBody() 메소드로 넣을 수 있다.

Person person = ... ;

    Mono<Void> result = client.post()
            .uri("/persons/{id}", id)
            .contentType(MediaType.APPLICATION_JSON)
            .syncBody(person)
            .retrieve()
            .bodyToMono(Void.class);

form data를 넣고 싶으면 MultiValueMap형태로 body에 넣을 수 있다. 이 경우 자동으로 콘텐트 타입이 ‘application/x-www-form-urlencoded’로 셋팅된다.

MultiValueMap<String, String> formData = ... ;

    Mono<Void> result = client.post()
            .uri("/path", id)
            .syncBody(formData)
            .retrieve()
            .bodyToMono(Void.class);


[https://dreamchaser3.tistory.com/11](https://dreamchaser3.tistory.com/11] [https://tanzu.vmware.com/developer/guides/spring-webclient-gs/](https://tanzu.vmware.com/developer/guides/spring-webclient-gs/) [https://wedul.site/670](https://wedul.site/670) [https://lts0606.tistory.com/305](https://lts0606.tistory.com/305) [https://www.cognizantsoftvision.com/blog/getting-started-with-reactive-spring-spring-webflux/](https://www.cognizantsoftvision.com/blog/getting-started-with-reactive-spring-spring-webflux/)

评论

此博客中的热门博文

R 함수

cut() cut  : 숫자들을 구간에 따라 분류해 factor로 변환한다. cut(x, breaks, right = F) # x는 숫자 vector # breaks는 구간을 저장한 vector 또는 구간의 수 # right는 breaks로 나뉘어진 구간에서 오른쪽 끝 값 사용에 대한 논리값 (T/F)으로, right = F의 경우 [a, b)로 됨 cut()에서 구간들은 (start, end] 형태로 정의되고, 0 < x <= end를 의미한다. 1~10사이의 수가 breaks에서 나눈 (0,5]와 (5, 10]구간에서 어느 곳에 속하는지 나타내는 factor를 반환한다.

Python - Numpy

random module np.random. normal (loc = 0.0, scale = 1.0, size = None) 정규 분포 확률 밀도에서 표본 추출함. 생성된 난수는 정규 분포의 형상을 가짐 Parameters: loc :  정규분포 평균 ( 중심점 ) scale :  표준편차 size : Output shape.  개수 혹은  ( 행 ,  열 ) Returns: out :  설정된  parameters 에 따른   ndarray or scalar  값을 반환 ex) np.random.normal(0, 1, (2, 3)) 평균이 0 이고 표준편차가 1 인 정규분포를 띄는 2x3 의 행렬 값을 반환 받음

기초 통계 함수

데이터의 기본적인 특징을 알려주는 기초 통계량  평균 분산 표준 편자 다섯 수 치 요약 최빈값 평균 (Mean) 평균을 계산한다. mean  : 평균을 계산한다. mean( x, trim=0, na.rm=FALSE, ...) # trim은 절사평균 을 사용할 때 (0, 0.5)로 지정 # na.rm는 평균 계산전 NA를 제거할지 여부 절사평균 (Trimmed Mean)이란?    데이터를 크기 순서로 나열한 뒤 값이 작은 쪽과 큰 쪽에서 얼마만큼의 데이터를 제거한 다음 평균을 계산 분산 (var) var  : 분산을 계산한다. var(x, na.rm=FALSE) > var(1:5) [1] 2.5 > var(mpg) [1] 36.3241028225806 표준 편차 (sd) sd:  표준 편차를 계산한다. sd(x, na.rm=FALSE) 다섯 수치 요약 최소값, 제1사분위수, 중앙값, 제3분위수, 최댓값으로 요약 fivenum  : 다섯 수치 요약을 구한다. fivenum(x, na.rm=TRUE) summary는 fivenum과 유사하지만 추가로 평균까지 계산한다. 최빈값(mode) 데이터에서 가장 자주 나타난 값을 말한다. table()을 사용해 각 데이터가 출현한 횟수를 센 분할표(Contigency Table)를 만든다. table  : 분할표를 작성한다. table( ... # 팩터로 해석할 수 있는 하나 이상의 객체 ) 반환 값은 table 클래스의 인스턴스이고 인자에 지정한 팩터들의 빈도수를 구한 결과를 저장 분할표(Contigency Table)란? 값의 빈도를 변수들의 값에 따라 나누어 그린 표