Spring WebFlux: WebClient объединяет 2 реактивных веб-сервиса RESTful - PullRequest
0 голосов
/ 05 мая 2018

Я работаю над приложением Microservices с поддержкой Reactive с использованием Spring WebFlux. Давайте посмотрим, у меня есть список вопросов, принадлежащих к категории и список вариантов для каждого вопроса. Я разделяю вопрос и опцию на сервисы с поддержкой Reactive и хочу, чтобы другой сервис объединял их вместе с помощью WebClient of Spring WebFlux. Конечно, он также должен поддерживать Reactive.

QuestionServiceImpl:

public Flux<Question> getQuestions(String categoryId) {
    WebClient client = WebClient
        .builder()
        .baseUrl(getServiceUrl())
        .build();

    WebClient.ResponseSpec responseSpec = client
        .get()
        .uri("/questions/" + categoryId)
        .retrieve();

    return responseSpec.bodyToFlux(Question.class);
}

OptionServiceImpl:

public Flux<Option> getOptions(String questionId) {
    WebClient client = WebClient
            .builder()
            .baseUrl(getServiceUrl())
            .build();

        WebClient.ResponseSpec responseSpec = client
            .get()
            .uri("/options/" + questionId)
            .retrieve();

        return responseSpec.bodyToFlux(Option.class);
}

Но я не знаю, как комбинировать вопрос с его вариантами реактивным способом. Кто-нибудь может предложить какие-то идеи?

Обновленное решение:

Я добавил новый класс с именем CompositeQuestion

@Data
@AllArgsConstructor 
public class CompositeQuestion {

    private String id;

    private String description;

    private String categoryId;

    private List<Option> options;

}

и теперь, чтобы получить список опций для вопроса, мой код такой:

Flux<CompositeQuestion> compositQuestion = questionsFromCoreQuestionService.flatMap(question ->
        optionService.getOptions(question.getId())
            .collectList()
            .map(options -> new CompositeQuestion(question.getId(), question.getDescription(), question.getCategoryId(), options)))
        .subscribeOn(Schedulers.elastic());

1 Ответ

0 голосов
/ 06 мая 2018

Предположим, у вас есть класс, подобный следующему:

@Value
public class QuestionOptions {
     private Question question;
     private List<Option> options;
}

(аннотация @ Value от Lombok )

Вы можете получить вопрос с его параметрами, такими как:

Flux<String> categoryIds = Flux.just("1", "2", "3");
Flux<QuestionOptions> questionOptions = 
    categoryIds.flatMap(categoryId -> 
         // retrieve questions for each category
         questionService.getQuestions(categoryId)
              // get options for each question 
              .flatMap(question -> optionService.getOptions(question.getId())
              .collectList()
              .map(optionList -> new QuestionOptions(question, optionList))
         ))
    .subscribeOn(Schedulers.elastic()); // retrieve each question on a different thread.

Обратите внимание, что если порядок категорий может отличаться от того, который вы запрашивали. Если для вас это нарушает условия сделки, вы можете рассмотреть возможность использования concatMap() вместо flatMap(), хотя каждый запрос будет выполняться последовательно.

...