page param
cursor or token param
Link: to next in response header
nextUrl in response body
perPage or pageSize paramUnfortunately, no standard.
page, perPage, cursor parametershttr2::req_retry()
max_tries or max_secondshttr2::req_cache() = save responses locally if server says its okpathWe’re going to req_retry() + req_cache() a lot, so:
req_perform()next_req functionsparam_name = "page" or whatever API calls itstart, offset = almost always leave as-isresp_pages = function to convert resp to page count
max_reqs <- min(max_reqs, total_pages)resp_complete = function to check if resp is last page
\(resp) !length(resp_body_json(resp))param_name = "cursor" or whatever API calls itresp_param_value = function to convert resp to next cursor
NULL if no more pagescrossref_multi <-
crossref_request_cursor |>
req_retry(max_tries = 3) |>
req_perform_iterative(
next_req = iterate_with_cursor(
"cursor",
resp_param_value = \(resp) {
content <- resp_body_json(resp)
if (!length(content$message$items)) {
return(NULL)
}
content$message$`next-cursor`
}
),
max_reqs = Inf
)
length(crossref_multi)
#> [1] 706rel = "next" or whatever API calls itresp_param_value = function to convert resp to next cursor
NULL if no more pagesmtg_cards_single <-
mtg_cards_request |>
req_perform()
resp_header(mtg_cards_single, "link")
#> <https://api.magicthegathering.io/v1/cards?name=bee&page=5&pageSize=20>; rel="last",
#> <https://api.magicthegathering.io/v1/cards?name=bee&page=2&pageSize=20>; rel="next"
mtg_cards_content <- mtg_cards_single |>
resp_body_json()nextUrl in response body
free_dictionary_request <-
request("https://api.dictionaryapi.dev/api/v2/entries/en/") |>
req_friendly(cache_name = "free_dictionary")
words <- c("hello", "world", "goodbye")
free_dictionary_reqs <-
purrr::map(words, \(word) req_url_path_append(free_dictionary_request, word))
free_dictionary_reqs |> purrr::map_chr("url")#> [1] "https://api.dictionaryapi.dev/api/v2/entries/en/hello"
#> [2] "https://api.dictionaryapi.dev/api/v2/entries/en/world"
#> [3] "https://api.dictionaryapi.dev/api/v2/entries/en/goodbye"
httr2::req_perform_parallel() performs multiple requests simultaneously
req_retry() (and some other things)req_perform_*() returns list of responsesresps_data() takes that list + resp_data parsing function and mergesresp_body_json
candidates_multi_results <- resps_data(
candidates_multi, fec_resp_parser
)
tibblify::tibblify(candidates_multi_results)#> # A tibble: 173 × 24
#> active_through candidate_id candidate_inactive candidate_status cycles
#> <int> <chr> <lgl> <chr> <list>
#> 1 2020 P00014241 FALSE N <list [3]>
#> 2 2024 P00008193 FALSE N <list [4]>
#> 3 2020 P00006296 FALSE P <list [4]>
#> 4 2020 P00010900 FALSE N <list [1]>
#> 5 2020 P00012104 FALSE P <list [3]>
#> 6 2020 P40003170 FALSE N <list [5]>
#> 7 2020 P00008128 FALSE N <list [4]>
#> 8 2020 P80004369 FALSE N <list [2]>
#> 9 2020 P00010090 FALSE N <list [3]>
#> 10 2024 P00015297 FALSE N <list [3]>
#> # ℹ 163 more rows
#> # ℹ 19 more variables: district <chr>, district_number <int>,
#> # election_districts <list>, election_years <list>, federal_funds_flag <lgl>,
#> # first_file_date <chr>, has_raised_funds <lgl>,
#> # inactive_election_years <list>, incumbent_challenge <chr>,
#> # incumbent_challenge_full <chr>, last_f2_date <chr>, last_file_date <chr>,
#> # load_date <chr>, name <chr>, office <chr>, office_full <chr>, …
req_perform_iterative on_error arg: “stop” or “return”resps_successes() extracts just successes from resps listresps_failures() same, but failuresresps_requests() to see how they were calledDSLC.io/wapir | Jon Harmon | wapir.io