The key piece that makes req_perform_iterative()
work is the next_req()
argument. For most common cases, you can use one of the canned helpers,
like iterate_with_offset()
. If, however, the API you're wrapping uses a
different pagination system, you'll need to write your own. This section
gives some advice.
Generally, your function needs to inspect the response, extract some data
from it, then use that to modify the previous request. For example, imagine
that the response returns a cursor, which needs to be added to the body of
the request. The simplest version of this function might look like this:
next_req <- function(resp, req) {
cursor <- resp_body_json(resp)$next_cursor
req |> req_body_json_modify(cursor = cursor)
}
There's one problem here: if there are no more pages to return, then
cursor
will be NULL
, but req_body_json_modify()
will still generate
a meaningful request. So we need to handle this specifically by
returning NULL
:
next_req <- function(resp, req) {
cursor <- resp_body_json(resp)$next_cursor
if (is.null(cursor))
return(NULL)
req |> req_body_json_modify(cursor = cursor)
}
A value of NULL
lets req_perform_iterative()
know there are no more
pages remaining.
There's one last feature you might want to add to your iterator: if you
know the total number of pages, then it's nice to let
req_perform_iterative()
know so it can adjust the progress bar.
(This will only ever decrease the number of pages, not increase it.)
You can signal the total number of pages by calling signal_total_pages()
,
like this:
next_req <- function(resp, req) {
body <- resp_body_json(resp)
cursor <- body$next_cursor
if (is.null(cursor))
return(NULL) signal_total_pages(body$pages)
req |> req_body_json_modify(cursor = cursor)
}