Повторите получение WebClient с новыми параметрами - PullRequest
0 голосов
/ 07 февраля 2019

Я занимаюсь разработкой приложения Spring WebFlux, и у меня есть веб-адаптер, который я использую для вызова внешних методов API, которые я использую.Один из apis имеет разбитый на страницы результат, используя заголовок ссылки с rel = "next".Мне нужно вызывать этот API до тех пор, пока не появится следующая ссылка, но я не уверен, как этого добиться.Ниже приведен базовый вызов, который я сейчас использую:

public Flux<ItemDto> getAllItems(){
   return webClient.get() //The headers and base url for the api are defined in the constructor
        .uri("/api/items?limit=200") //limit is the number of items returned with 200 being the maximum
        .retrieve()
        .bodyToFlux(Map.class)
        .map(ItemConverter::mapValueToItemDto);//This is just a conversion method that handles mapping
}

Мне нужно иметь возможность повторить этот вызов, но добавить параметр запроса, основанный на части заголовка ссылки со следующим:"rel value.

Я видел упоминание об использовании расширения или повторения, но я не уверен, как именно их использовать.Я знаю, что использование exchange необходимо для получения clientResponse, чтобы я мог получить заголовки.

Этот вопрос, вероятно, довольно неопределенный, поэтому я могу дать любые разъяснения, если это необходимо.

Спасибо!

ОБНОВЛЕНИЕ

Я пытался делать разные вещи инашел что-то, что почти работает.

public Flux<ItemDto> getAllItems(){
   return recursiveMethod("")//Start with the first page basically
      .flatMap(clientResponse ->
           clientResponse.bodyToFlux(Map.class)
                .map(ItemConverter::mapValueToItemDto));
}

private Flux<ClientResponse> recursiveMethod(String after){
   return webClient.get()
            .uri("/api/items?limit=3" + after) //The test list I am using is only 9 items so I'm using 3 for good results
            .exchange()
            .expand(clientResponse -> {
                List<String> links = clientResponse.headers().asHttpHeaders().getValuesAsList("LINK");
                if(links.stream().anyMatch(link->link.contains("rel=\"next\""))){
                    for (String link : links){
                        if (link.contains("rel=\"next\"")){
                            return recursiveMethod("&" + link.substring(link.indexOf("after="), link.indexOf("&"))); 
                            //The header link has limit and after switched, that's why this looks a little odd
                        }
                    }
                }
                return Flux.empty();
            });
}

Единственная проблема состоит в том, что он заканчивает тем, что повторял последнюю «страницу», например: Элемент 1, Элемент 2, Элемент 3, Элемент 4, Элемент 5, Элемент 6,Item 7, Item 8, Item 9, Item 7, Item 8, Item 9. Не уверен, что это из-за рекурсии, которую я настроил, или из-за Flux, или потому, что я возможно неправильно использую метод расширения.

1 Ответ

0 голосов
/ 11 февраля 2019

После долгих проб и ошибок и поиска решений для конкретных частей этого я нашел решение, которое сработало для меня.

public Flux<ItemDto> getAllItems() {
    webClient.get()
            .uri("/api/items?limit=1")//Used one to test
            .exchange()
            .expand(clientResponse -> {
                List<String> links = clientResponse.headers().asHttpHeaders().getValuesAsList("LINK");
                if(links.stream().anyMatch(link->link.contains("rel=\"next\""))){
                    for (String link : links){
                        if (link.contains("rel=\"next\"")){
                            return webClient.get()
                                    .uri("/api/items?limit=1&" + link.substring(link.indexOf("after="), link.indexOf("&")))
                                    .exchange();
                        }
                    }
                }
                return Flux.empty();
            })
            .flatMap(clientResponse ->
                    clientResponse.bodyToFlux(Map.class)
                            .map(ItemConverter::mapValueToItemDto));
}

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

webClient.get()
   .uri("/api/items?limit=1" + after)//This after bit would be like what was passed as an argument before
   .exchange();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...