我正在尝试弄清如何以反应式方式使用分页的API,公开项目流而不是API给我的页面。
Slack API(以及许多其他API)处理某种形式的元数据对象的分页,以便在对/api/stuff
的查询中,您可以返回如下对象:
{
"items": [ <list of first page you requested> ],
"meta": {
"cursor": "<a cursor string to get the next page>"
}
}
然后您可以使用GET /api/stuff?cursor=<the cursor from above>
请求下一页,并且在响应中您将获得一个新的游标,因此可以继续进行直到获得一个游标为空的响应-那时最后一个可用页面。
使用Reactor,我想提供一种返回类型为Flux<Item>
的方法,即所有项目的流,消费者不需要知道或关心这些项目实际上是在哪一页获取的时间。
基本上,我想做一些事情,采取一种初始状态,并使用签名为State -> Mono<Tuple2<Collection<Item>, State>>
(或等价物)的方法,并通过依次获取新页面直到{ {1}}表示我们已经完成。
我尝试使用Flux<Item>
或State
来表述某些内容,但似乎它们的用例与我的用例略有不同。
答案 0 :(得分:0)
我是反应堆新手,但是我认为expand()的用途是
这是一个完整的演示,其中getFirstPage()
和getNextPage()
模拟了松弛API。当光标到达值5时,getNextPage()
返回最后一页。
public class Slack {
public static void main(String[] args) {
getFirstPage().expand(page -> getNextPage(page))
.flatMapIterable(page -> page.getResult())
.subscribe(System.out::println);
}
private static Mono<Page> getFirstPage() {
System.out.println("getting first page");
return Mono.just(new Page(Arrays.asList("page0-1", "page0-2"), 1));
}
private static Mono<Page> getNextPage(Page page) {
System.out.println("getting page " + page.getCursor());
if (page.getCursor() == null) {
return Mono.empty();
}
Integer nextCursor = (page.getCursor() == 5) ? null : page.getCursor() + 1;
return Mono.just(new Page(Arrays.asList("page" + page.getCursor() + "-1", "page" + page.getCursor() + "-2"), nextCursor));
}
static class Page {
private List<String> result;
private Integer cursor;
public Page(List<String> result, Integer cursor) {
this.result = result;
this.cursor = cursor;
}
public List<String> getResult() {
return result;
}
public Integer getCursor() {
return cursor;
}
}
}