API Calls Exercises in R: 15 Practice Problems

Fifteen practice problems on REST API calls in R with httr2 and jsonlite: GET, POST, headers, auth, JSON, pagination. Hidden solutions.

library(httr2)
library(jsonlite)
library(dplyr)

Exercise 1: Basic GET

Difficulty: Beginner.

Show solution
request("https://httpbin.org/get") |> req_perform() |> resp_body_json()

Exercise 2: GET with query parameters

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/get") |>
  req_url_query(name = "alice", role = "admin") |>
  req_perform() |> resp_body_json()

Exercise 3: Add header

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/get") |>
  req_headers(`X-Custom` = "value") |>
  req_perform()

Exercise 4: POST JSON

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/post") |>
  req_body_json(list(a = 1, b = "hello")) |>
  req_perform() |> resp_body_json()

Exercise 5: POST form

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/post") |>
  req_body_form(name = "alice") |>
  req_perform()

Exercise 6: Bearer auth

Difficulty: Advanced.

Show solution
request("https://api.example.com") |>
  req_auth_bearer_token("xxxxxxx")

Exercise 7: Basic auth

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/basic-auth/user/passwd") |>
  req_auth_basic("user", "passwd") |>
  req_perform()

Exercise 8: Inspect raw response

Difficulty: Intermediate.

Show solution
resp <- request("https://httpbin.org/get") |> req_perform()
list(status = resp_status(resp), headers = resp_headers(resp))

Exercise 9: Retry on failure

Difficulty: Advanced.

Show solution
request("https://httpbin.org/status/500") |>
  req_retry(max_tries = 3) |>
  req_error(is_error = function(resp) FALSE) |>
  req_perform()

Exercise 10: Throttle requests

Difficulty: Advanced.

Show solution
request("https://httpbin.org/get") |>
  req_throttle(rate = 2 / 60)   # 2 req/min

Exercise 11: Parse JSON to tibble

Difficulty: Intermediate.

Show solution
j <- '[{"id":1,"name":"a"},{"id":2,"name":"b"}]'
fromJSON(j) |> as_tibble()

Exercise 12: Convert tibble to JSON

Difficulty: Intermediate.

Show solution
toJSON(head(mtcars, 3), pretty = TRUE)

Exercise 13: Pagination via loop

Difficulty: Advanced.

Show solution
# all_results <- list()
# page <- 1
# repeat {
#   resp <- request("https://api.example.com") |>
#     req_url_query(page = page) |> req_perform() |> resp_body_json()
#   if (length(resp$results) == 0) break
#   all_results <- c(all_results, resp$results)
#   page <- page + 1
# }

Exercise 14: Save response body

Difficulty: Intermediate.

Show solution
request("https://httpbin.org/get") |>
  req_perform(path = "response.json")

Exercise 15: Handle non-2xx

Difficulty: Advanced.

Show solution
resp <- request("https://httpbin.org/status/404") |>
  req_error(is_error = function(resp) FALSE) |>
  req_perform()
resp_status(resp)

What to do next

  • Web-Scraping-Exercises (shipped), HTML extraction.
  • purrr-Exercises (shipped), safely/possibly for resilient API loops.