На основе Как собирать API-ответы с разбивкой по страницам с помощью весенней загрузки WebClient?
Я создал следующий класс искателя
class GitlabCrawler(private val client: WebClient, private val token: String) {
fun fetchCommits(project: URI): Flux<Commit> {
return fetchCommitsInternal(project).expand { cr: ClientResponse? ->
val nextUrl = getNextUrl(cr)
nextUrl?.let { fetchCommitsInternal(URI.create(it)) }
?: Mono.empty<ClientResponse>()
}.limitRate(1)
.flatMap { cr: ClientResponse? -> cr?.bodyToFlux(Commit::class.java) ?: Flux.empty() }
}
private fun getNextUrl(cr: ClientResponse?):String? {
// TODO replace with proper link parsing
return cr?.headers()?.header(HttpHeaders.LINK)?.firstOrNull()
?.splitToSequence(",")
?.find { it.endsWith("rel=\"next\"") }
?.let { it.substring(it.indexOf('<') + 1, it.lastIndexOf('>')) }
}
private fun fetchCommitsInternal(url: URI): Mono<ClientResponse> {
return client.get()
.uri(url)
.accept(MediaType.APPLICATION_JSON_UTF8)
.header("Private-Token", token)
.exchange()
}
}
data class Commit(
val id: String,
val message: String,
@JsonProperty("parent_ids") val parentIds: List<String>,
@JsonProperty("created_at") val createdAt: String)
Я бы хотел избежать ненужныхзапрос, но он выполняет больше запроса, чем необходимо для его выполнения.
gitlabCrawler.fetchCommits(URI.create("https://...")).take(15).collectList().block()
Потребуется только один запрос, поскольку каждая страница содержит 20 записей, но он запускает запрос второй страницы.Кажется, всегда запрашивать еще одну страницу, чем необходимо.Я пытался использовать limitRate
, но это, похоже, не дает эффекта.
Есть ли способ сделать его ленивым, то есть запрашивать следующую страницу только тогда, когда ток исчерпан?