Использование весеннего webflux для потребления двух apis один за другим - PullRequest
0 голосов
/ 26 сентября 2018

Мне нужно написать новый API, который будет принимать некоторые параметры, потреблять и существующие API, а затем использовать результаты этого, чтобы потреблять второй существующий API.Я не использовал Spring 5 раньше, но заметил, что шаблон rest будет устаревшим, и вместо этого я должен использовать webflux.Я сделал несколько уроков по простым случаям, но не уверен, как решить мою конкретную проблему.

Учитывая, что у меня есть следующие два API:

@GetMapping("/foo/{id}")
public Foo getById(@PathVariable int id) {
    return new Foo(id, "foo");
}

@PostMapping("/bar")
public Bar createBar(@RequestBody Bar bar) {
    return bar;
}

И у меня есть новое приложение Springbootсодержащий новый API:

@SpringBootApplication
@RestController
public class ReactiveClientApplication {
    @Bean
    WebClient fooWebClient() {
        return WebClient.builder()
            .baseUrl("http://localhost:8080/foo")
            .build();
    }

    @Bean
    WebClient barWebClient() {
        return WebClient.builder()
            .baseUrl("http://localhost:8080/bar")
            .build();
    }

    // This works fine
    @PostMapping("/foo/{fooId}")
    public Mono<Foo> foo(@PathVariable Integer fooId) {
        return fooWebClient()
            .get()
            .uri("/{id}", fooId)
            .retrieve()
            .bodyToMono(Foo.class);
    }

    // This works fine
    @PostMapping("/bar")
    public Mono<Bar> bar() {
        return barWebClient()
            .post()
            .body(Mono.just(new Bar("bar", new Date())), Bar.class)
            .retrieve()
            .bodyToMono(Bar.class);
    }

    // I cannot get this to work
    @PostMapping("/foobar/{fooId}")
    public Mono<Bar> fooBar(@PathVariable Integer fooId) {
        Mono<Foo> fooMono = fooWebClient().get().uri("/{id}", fooId).retrieve().bodyToMono(Foo.class);
        fooMono.flatMap(foo -> {
            Mono<Bar> barMono = barWebClient().post().body(Mono.just(new Bar(foo.getFooStuff(), new Date())), Bar.class)
                    .retrieve().bodyToMono(Bar.class);
            return barMono;
        });
        return null;
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(ReactiveClientApplication.class)
            .properties(Collections.singletonMap("server.port", "8081"))
            .run(args);
    }
}

Метод foobar должен вызывать и ждать ответа foo, используйте его для вызова панели, а затем дождитесь ответа и верните его.

IЯ думаю, мне, очевидно, нужно приложить немного больше усилий, чтобы узнать, как все это работает, но я надеялся, что кто-то сможет указать мне правильное направление, как мне следует это делать.

Спасибо!

1 Ответ

0 голосов
/ 27 сентября 2018

Вы не должны возвращать ноль.А как насчет следующего кода:

@PostMapping("/foobar/{fooId}")
public Mono<Bar> fooBar(@PathVariable Integer fooId) {
    Mono<Foo> fooMono = fooWebClient().get().uri("/{id}", fooId).retrieve().bodyToMono(Foo.class);
    return fooMono.flatMap(foo -> 
                 barWebClient()
                    .post()
                    .body(Mono.just(new Bar(foo.getFooStuff(), new Date())), Bar.class)
                    .retrieve()
                    .bodyToMono(Bar.class)
    );
}
...