반응형

WebClient를 사용하는 코드를 테스트하려면 OkHttp MockWebServer 등의 모의 Web 서버를 사용할 수 있다. 사용 예는 Spring Framework 테스트 스위트 WebClientIntegrationTests 또는 OkHttp 저장소 static-server의 샘플을 참조해라.

반응형
반응형

WebClient는 결과 마지막으로 차단하여, 동기화 스타일로 사용할 수 있다.

Java

Person person = client.get().uri("/person/{id}", i).retrieve()
    .bodyToMono(Person.class)
    .block();

List<Person> persons = client.get().uri("/persons").retrieve()
    .bodyToFlux(Person.class)
    .collectList()
    .block();

Kotlin

val person = runBlocking {
    client.get().uri("/person/{id}", i).retrieve()
            .awaitBody<Person>()
}

val persons = runBlocking {
    client.get().uri("/persons").retrieve()
            .bodyToFlow<Person>()
            .toList()
}

단, 여러번 호출할 필요가 있는 경우는 각 응답을 개별적으로 차단하는 것을 피하고 대신에 결합된 결과를 기다리는 것이 더 효율적이다.

Java

Mono<Person> personMono = client.get().uri("/person/{id}", personId)
        .retrieve().bodyToMono(Person.class);

Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)
        .retrieve().bodyToFlux(Hobby.class).collectList();

Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {
            Map<String, String> map = new LinkedHashMap<>();
            map.put("person", person);
            map.put("hobbies", hobbies);
            return map;
        })
        .block();

Kotlin

val data = runBlocking {
        val personDeferred = async {
            client.get().uri("/person/{id}", personId)
                    .retrieve().awaitBody<Person>()
        }

        val hobbiesDeferred = async {
            client.get().uri("/person/{id}/hobbies", personId)
                    .retrieve().bodyToFlow<Hobby>().toList()
        }

        mapOf("person" to personDeferred.await(), "hobbies" to hobbiesDeferred.await())
    }

위는 단순한 예이다. 많은 원격 호출을 만든 리액티브 파이프 라인을 정리하는 다른 패턴과 연산자가 많이 있다.

FluxMono에서는 Spring MVC 또는 Spring WebFlux 컨트롤러를 차단할 필요가 없다. 컨트롤러 메소드에서 결과의 리액티브 형을 돌려 줄뿐이다. 같은 원칙이 Kotlin 코루틴과 Spring WebFlux에도 적용된다. 컨트롤러 메소드에서 중단 기능을 사용하거나 Flow를 돌려 줄뿐이다.

반응형
반응형

속성(Attributes)은 정보를 필터 체인에 전달하는 편리한 방법을 제공하지만, 현재 요청에만 영향을 준다. 중첩된 추가 요청에 전파하는 정보를 전달하려면, flatMap를 통해 또는 후에 실행된다. concatMap를 통한 경우는 Reactor Context를 사용해야 한다.

Reactor Context는 모든 작업에 적용하기 위해 리액티브 체인의 마지막에 입력해야 한다. 예 :

Java

WebClient client = WebClient.builder()
        .filter((request, next) ->
                Mono.deferContextual(contextView -> {
                    String value = contextView.get("foo");
                    // ...
                }))
        .build();

client.get().uri("https://example.org/")
        .retrieve()
        .bodyToMono(String.class)
        .flatMap(body -> {
                // perform nested request (context propagates automatically)...
        })
        .contextWrite(context -> context.put("foo", ...));
반응형
반응형

요청에 속성을 추가 할 수 있다. 이것은 정보를 필터 체인에 전달 특정 요청에 대한 필터의 동작에 영향을 미치는 경우에 유용하다. 예를 들면 아래와 같다.

Java

WebClient client = WebClient.builder()
        .filter((request, next) -> {
            Optional<Object> usr = request.attribute("myAttribute");
            // ...
        })
        .build();

client.get().uri("https://example.org/")
        .attribute("myAttribute", "...")
        .retrieve()
        .bodyToMono(Void.class);

    }

Kotlin

val client = WebClient.builder()
        .filter { request, _ ->
            val usr = request.attributes()["myAttribute"];
            // ...
        }
        .build()

    client.get().uri("https://example.org/")
            .attribute("myAttribute", "...")
            .retrieve()
            .awaitBody<Unit>()

defaultRequest 콜백을 WebClient.Builder 레벨에서 글로벌 구성을 할 수 있는 점에 유의해라. 이렇게 하면 모든 요청에 속성을 삽입 할 수 있다. 이는 예를 들어 Spring MVC 응용 프로그램에서 사용하여 ThreadLocal 데이터를 기반으로 요청 속성을 설정할 수 있다.

반응형
반응형

요청에 속성을 추가 할 수 있다. 이것은 정보를 필터 체인에 전달 특정 요청에 대한 필터의 동작에 영향을 미치는 경우에 유용하다. 예를 들면 아래와 같다.

Java

WebClient client = WebClient.builder()
        .filter((request, next) -> {
            Optional<Object> usr = request.attribute("myAttribute");
            // ...
        })
        .build();

client.get().uri("https://example.org/")
        .attribute("myAttribute", "...")
        .retrieve()
        .bodyToMono(Void.class);

    }

Kotlin

val client = WebClient.builder()
        .filter { request, _ ->
            val usr = request.attributes()["myAttribute"];
            // ...
        }
        .build()

    client.get().uri("https://example.org/")
            .attribute("myAttribute", "...")
            .retrieve()
            .awaitBody<Unit>()

defaultRequest 콜백을 WebClient.Builder 레벨에서 글로벌 구성을 할 수 있는 점에 유의해라. 이렇게 하면 모든 요청에 속성을 삽입 할 수 있다. 이는 예를 들어 Spring MVC 응용 프로그램에서 사용하여 ThreadLocal 데이터를 기반으로 요청 속성을 설정할 수 있다.

반응형

+ Recent posts