Как я могу вернуть Flux‹Order›, когда мой ответ заключен в объект разбиения на страницы json с помощью Spring 5?

У меня есть веб-служба, которую я пытаюсь использовать с новым веб-клиентом Spring 5.

Рабочий пример

# GET /orders/
[
    { orderId: 1, ... },
    { orderId: 1, ... }
]

И java-код для вызова

// Java
Flux<Order> ordersStream = webClient.get()
    .uri("/orders/")
    .exchange()
    .flatMap(response -> response.bodyToFlux(Order.class));

Проблема

Ответ от веб-службы разбивается на страницы и поэтому не содержит непосредственно списка элементов, как в приведенном выше примере.

Это выглядит так

# GET /orders/
{
    "error": null,
    "metadata": {
      "total": 998,
      "limit": 1000,
      "offset": 0
    },
    "data": [
       { orderId: 1, ... },
       { orderId: 2, ... },
    ]
}

Как я могу получить дополнительный ключ "data" как Flux<Order>?

Возможное решение, но я не знаю, лучший ли это подход...

Создайте класс-оболочку и преобразуйте оболочки .data в поток.

Но теперь нам нужно десериализовать весь ответ сразу, что может привести к нехватке памяти.

// Java
Flux<Order> ordersStream = webClient.get()
    .uri("/orders/")
    .exchange()
    .flatMap(response -> response.bodyToMono(PageWrapper.class))
    .flatMapMany(wrapper -> Flux.fromIterable(wrapper.data));

Есть ли способ лучше?


person Leon Radley    schedule 10.06.2017    source источник
comment
Не могли бы вы предоставить больше контекста, пожалуйста? Что именно вы хотите сопоставить с типом Order? Каждый отдельный элемент в data?   -  person systemfreund    schedule 14.06.2017
comment
@systemfreund Я обновил вопрос, указав дополнительный контекст.   -  person Leon Radley    schedule 15.06.2017
comment
Я не думаю, что есть готовое решение для этого. Вам нужно будет работать на уровне Flux<DataBuffer>, чтобы анализировать json на низком уровне, а затем выдавать экземпляры Order, как только будет накоплено достаточно данных. На самом деле именно так это делает веб-клиент: см. org.springframework.http.codec.json.JsonObjectDecoder. Этот декодер используется для повторного разделения необработанных данных, чтобы границы блоков были выровнены с допустимыми объектами json.   -  person systemfreund    schedule 16.06.2017
comment
Я тоже в замешательстве по этому поводу. spring-webflux и пружинные данные ReactiveXXXRepsoitory в общем случае не включают API-интерфейсы с возможностью просмотра страниц. И Flux означает живые данные в потоке. Есть ли хороший способ позволить Flux однократно передавать лимит данных от подписчика?   -  person Hantsy    schedule 21.08.2017