복붙노트

[SPRING] 스프링 부트 WebClient를 사용하여 페이지 매김 된 API 응답을 수집하는 방법?

SPRING

스프링 부트 WebClient를 사용하여 페이지 매김 된 API 응답을 수집하는 방법?

URL에서 페이지가 매겨진 응답이 있는데 이전 응답에서 가져온 다음 페이지 URL을 계속 누르고 싶고 내 응답에 "nextPage"URL이 없을 때까지 항목을 수집합니다. 블로킹없이 WebFlux에서 스프링 부트 WebClient를 사용하여 사기성 방법으로이를 수행하는 방법은 무엇입니까?

Request1: 

    GET /items
    response: 
    {
        items: [...]
        nextPage: "/items?page=2"
    }


    Request2: 

    GET /items?page=2
    response: 
    {
        items: [...]
        nextPage: "/items?page=3"
    }


    Request3: 

    GET /items?page=3
    response: 
    {
        items: [...]
        nextPage: null
    }

여기 모의 (mock) URL을 만들었습니다. https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items?page=2 https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items?page=3

차단없이 반응식으로 위의 응답에서 모든 항목을 추출하려면 어떻게합니까?

해결법

  1. ==============================

    1.확장을 사용하면이 작업을 수행 할 수 있습니다. 귀하가 제공 한 모의 (mock) URL을 기반으로합니다.

    확장을 사용하면이 작업을 수행 할 수 있습니다. 귀하가 제공 한 모의 (mock) URL을 기반으로합니다.

    public Mono<List<Item>> getItems() {
        String url = "https://karthikdivi.com/apps/paginatedReviews/withNextPageTokens/items";
    
        return fetchItems(url).expand(response -> {
            if (response.getNextPage() == null) {
                return Mono.empty();
            }
            return fetchItems(response.getNextPage());
        }).flatMap(response -> Flux.fromIterable(response.getItems())).collectList();
    }
    
    private Mono<Response> fetchItems(String url) {
    
             return client.get().uri(url).retrieve()
                        .bodyToMono(Response.class);
        }
    
  2. ==============================

    2.다음을 사용하여 원하는 효과를 얻을 수 있습니다.

    다음을 사용하여 원하는 효과를 얻을 수 있습니다.

    @Test
    public void usingExpand(){
    
        Request innerData = new Request(null);
        Request middleData = new Request(innerData);
        Request rootData = new Request(middleData);
    
        Mono.just(rootData)
                .expand( t -> Mono.justOrEmpty(t.netxPage))
                .flatMap( t -> Flux.fromIterable(t.items))
                .subscribe(System.out::println);
    
    }
    
    public static class Request {
        List<String> items = new ArrayList<>();
        Request netxPage;
    
        public Request(Request netxPage) {
            this.items.add(UUID.randomUUID().toString());
            this.items.add(UUID.randomUUID().toString());
            this.netxPage = netxPage;
        }
    }
    

    위의 코드는 다음 결과를 생성합니다.

    dc78317c-5552-4723-90db-5392c67655be
    32ff12bb-5be1-415e-b481-dab85d9157dd
    cf1e3f36-a8e2-414d-90a2-7708eeedc5be
    91a6bc14-a396-483d-a66a-80bb98dc1968
    c95adae3-8e6f-489b-8a9d-4cea3080e150
    d6f8fe01-2c50-4574-958c-ec675331bb25
    

    각 데이터 객체의 두 UUID.

  3. from https://stackoverflow.com/questions/53274568/how-to-collect-paginated-api-responses-using-spring-boot-webclient by cc-by-sa and MIT license