R Academy · Lektion

REST-APIs in R verwenden

Authentifizieren Sie sich mit API-Schlüsseln, blättern Sie durch Ergebnisseiten und speichern Sie API-Antworten

Lektion 3 von 413 Schritte

REST-APIs in R verwenden ist eine kostenlose R Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des R Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Konzepte von REST-APIs

REST-APIs verwenden HTTP-Methoden (GET, POST, PUT, DELETE) für Ressourcen-URLs. Antworten liegen typischerweise als JSON vor. APIs können eine Authentifizierung erfordern, Paginierung verwenden und Ratenbegrenzungen durchsetzen. Ein guter R-API-Client kümmert sich um alle drei Aspekte.

library(httr2)

# REST API anatomy:
# Base URL:  https://api.example.com/v1
# Resources: /users, /products, /orders
# Methods:
#   GET    /users       -> list users
#   POST   /users       -> create user
#   GET    /users/42    -> get user 42
#   PUT    /users/42    -> update user 42
#   DELETE /users/42    -> delete user 42

# Query parameters for filtering/pagination:
# GET /users?page=2&size=20&sort=name

cat('REST = stateless + resource-based + HTTP methods')

Authentifizierung mit Bearer-Token

Die meisten modernen APIs verwenden Bearer-Token (OAuth 2.0). Speichern Sie das Token mit Sys.setenv() in einer Umgebungsvariablen oder in einer .Renviron-Datei. Schreiben Sie Token niemals fest in Skripte.

library(httr2)

# Store token securely in .Renviron:
# GITHUB_PAT=ghp_your_token_here

# Access at runtime:
token <- Sys.getenv('GITHUB_PAT')
if (nchar(token) == 0) token <- 'demo_token'

# Use in requests:
# resp <- request('https://api.github.com/user') |>
#   req_auth_bearer_token(token) |>
#   req_headers('Accept' = 'application/vnd.github.v3+json') |>
#   req_perform() |>
#   resp_check_status()

# result <- resp_body_json(resp)
# result$login  # your GitHub username
cat('Token from env:', if(nchar(token)>0) 'found' else 'missing')

Einen wiederverwendbaren API-Client erstellen

Kapseln Sie Basis-URL, Authentifizierung und Fehlerbehandlung in einer Konstruktorfunktion. Jeder API-Endpunkt wird zu einer Methode, die diese Basisfunktion aufruft – dies ist das Standardmuster für R-API-Pakete.

library(httr2)

# API client constructor
new_api_client <- function(base_url, token) {
  list(
    base_req = request(base_url) |>
      req_auth_bearer_token(token) |>
      req_headers('Accept' = 'application/json') |>
      req_retry(max_tries = 3)
  )
}

# Method: GET /users
get_users <- function(client, page = 1, size = 20) {
  resp <- client$base_req |>
    req_url_path_append('users') |>
    req_url_query(page = page, size = size) |>
    req_perform() |>
    resp_check_status()
  resp_body_json(resp, simplifyVector = TRUE)
}

# client <- new_api_client('https://api.example.com', token)
# users <- get_users(client, page = 1)
cat('Reusable client pattern: base request + methods')

Paginierung mit resp_link_url()

Viele APIs verwenden Link-Header für die Paginierung (RFC 5988): Die Antwort enthält einen Header Link: <url>; rel="next". resp_link_url(resp, 'next') extrahiert automatisch die URL der nächsten Seite.

library(httr2)

# Generic paginator using Link headers
fetch_all_pages <- function(initial_url, token, max_pages = 50) {
  all_results <- list()
  next_url <- initial_url
  page <- 1
  while (!is.null(next_url) && page <= max_pages) {
    resp <- request(next_url) |>
      req_auth_bearer_token(token) |>
      req_perform() |>
      resp_check_status()
    all_results[[page]] <- resp_body_json(resp, simplifyVector = TRUE)
    # Follow Link: <url>; rel='next' header
    next_url <- tryCatch(
      resp_link_url(resp, 'next'),
      error = function(e) NULL
    )
    page <- page + 1
  }
  do.call(rbind, all_results)
}
cat('resp_link_url() follows RFC 5988 pagination')

Cursor-basierte Paginierung

Einige APIs (Twitter, Slack) verwenden statt Seitennummern Cursor. Die Antwort enthält ein Feld next_cursor oder next_page_token. Übergeben Sie den Wert als Abfrageparameter für die nächste Anfrage.

library(httr2)

# Cursor-based pagination pattern
fetch_cursor_pages <- function(base_url, token, max_pages = 100) {
  all_data <- list()
  cursor <- NULL
  page <- 1
  repeat {
    req <- request(base_url) |>
      req_auth_bearer_token(token)
    if (!is.null(cursor))
      req <- req |> req_url_query(cursor = cursor)
    resp <- req |> req_perform() |> resp_check_status()
    body <- resp_body_json(resp)
    all_data[[page]] <- body$results
    cursor <- body$next_cursor  # NULL if last page
    if (is.null(cursor) || page >= max_pages) break
    page <- page + 1
  }
  do.call(c, all_data)
}
cat('Cursor pagination: safer for large/changing datasets')

Fehler angemessen behandeln

Ein API-Client für den Produktionseinsatz fängt HTTP-Fehler und Netzwerkausfälle getrennt ab. Verwenden Sie tryCatch() um req_perform() und untersuchen Sie die Fehlerbedingung httr2_http_*, um den Status gezielt zu behandeln.

library(httr2)

safe_api_call <- function(req) {
  tryCatch(
    req |> req_perform() |> resp_check_status(),
    httr2_http_401 = function(e) {
      stop('Authentication failed. Check your token.')
    },
    httr2_http_403 = function(e) {
      stop('Forbidden. Insufficient permissions.')
    },
    httr2_http_404 = function(e) {
      message('Resource not found, returning NULL')
      return(NULL)
    },
    httr2_http_429 = function(e) {
      stop('Rate limit exceeded. Try again later.')
    },
    error = function(e) {
      stop(paste('Request failed:', conditionMessage(e)))
    }
  )
}
cat('Match on specific httr2_http_NNN conditions')

API-Antworten zwischenspeichern

Speichern Sie API-Antworten im Cache, um während der Entwicklung unnötige Anfragen zu vermeiden. req_cache() in httr2 speichert Antworten unter Berücksichtigung der Cache-Control-Header auf der Festplatte. Manuelles Caching funktioniert mit jeder API.

library(httr2)

# httr2 built-in disk cache
# resp <- request('https://api.example.com/static-data') |>
#   req_cache(tempdir(), max_age = 3600) |>  # 1 hour TTL
#   req_perform()

# Manual cache pattern
cached_api_call <- function(url, cache_file, max_age = 3600) {
  if (file.exists(cache_file)) {
    age <- as.numeric(Sys.time() - file.mtime(cache_file))
    if (age < max_age) {
      cat('Cache hit\n')
      return(readRDS(cache_file))
    }
  }
  cat('Cache miss, fetching...\n')
  # result <- resp_body_json(request(url) |> req_perform())
  # saveRDS(result, cache_file)
  # result
}
cached_api_call('https://example.com/api', 'cache.rds')

Parallele Anfragen mit req_perform_parallel()

req_perform_parallel() sendet mehrere Anfragen gleichzeitig und verkürzt dadurch die Gesamtdauer von Stapelverarbeitungen erheblich. Kombinieren Sie die Funktion mit req_throttle(), um bei der parallelen Ausführung Ratenbegrenzungen einzuhalten.

library(httr2)

# Build a list of requests
item_ids <- 1:5
reqs <- lapply(item_ids, function(id) {
  request(paste0('https://jsonplaceholder.typicode.com/todos/', id))
})

# Execute all in parallel (requires internet)
# resps <- req_perform_parallel(
#   reqs,
#   on_error = 'continue',  # skip failures
#   progress = TRUE
# )
# results <- lapply(resps, resp_body_json)
# titles <- sapply(results, function(r) r$title)
# print(titles)

# on_error options:
# 'stop'     -> abort on first failure
# 'continue' -> collect errors, keep going
cat('Parallel: much faster for many independent calls')

Mit Ratenbegrenzungen arbeiten

APIs teilen den Status der Ratenbegrenzung über Antwort-Header mit: X-RateLimit-Remaining, X-RateLimit-Reset und Retry-After. Lesen Sie diese Header aus, um eine intelligente Wartezeitstrategie zu implementieren.

library(httr2)

respect_rate_limit <- function(resp) {
  # Check remaining calls
  remaining <- resp_header(resp, 'x-ratelimit-remaining')
  if (!is.na(remaining) && as.integer(remaining) < 5) {
    reset_at <- as.integer(
      resp_header(resp, 'x-ratelimit-reset')
    )
    wait_secs <- max(0, reset_at - as.integer(Sys.time()))
    cat(sprintf('Rate limit nearly exhausted. Waiting %ds\n', wait_secs))
    # Sys.sleep(wait_secs)
  }
  # Handle 429 Retry-After header
  if (resp_status(resp) == 429) {
    retry_after <- resp_header(resp, 'retry-after')
    cat(sprintf('Rate limited. Retry after %s seconds\n', retry_after))
  }
  resp
}
cat('Always respect X-RateLimit-* headers')

Vollständiger API-Client: GitHub-Beispiel

Hier wird alles zusammengeführt: ein vollständiger GitHub-API-Client, der sich authentifiziert, paginierte Repository-Listen abruft und Fehler behandelt – ein Beispiel für alle bisher gelernten Muster.

library(httr2)

# GitHub API client
github_repos <- function(username, token = NULL, n_pages = 3) {
  base <- 'https://api.github.com'
  req_base <- request(base) |>
    req_headers(
      'Accept'     = 'application/vnd.github.v3+json',
      'User-Agent' = 'R-API-Client/1.0'
    )
  if (!is.null(token))
    req_base <- req_base |> req_auth_bearer_token(token)

  all_repos <- list()
  for (page in seq_len(n_pages)) {
    # resp <- req_base |>
    #   req_url_path_append('users', username, 'repos') |>
    #   req_url_query(page = page, per_page = 30, sort = 'updated') |>
    #   req_perform() |> resp_check_status()
    # repos <- resp_body_json(resp, simplifyVector = TRUE)
    # if (length(repos) == 0) break
    # all_repos[[page]] <- repos
    cat(sprintf('Would fetch page %d for %s\n', page, username))
  }
  do.call(rbind, all_repos)
}
github_repos('hadley')

OAuth-2.0-Client-Credentials

Einige APIs erfordern den OAuth-2.0-Client-Credentials-Flow: Dabei werden client_id und client_secret gegen ein Zugriffstoken eingetauscht. oauth_client() und req_oauth_client_credentials() von httr2 erledigen dies automatisch.

library(httr2)

# OAuth 2.0 Client Credentials flow:
# client <- oauth_client(
#   id     = Sys.getenv('CLIENT_ID'),
#   secret = Sys.getenv('CLIENT_SECRET'),
#   token_url = 'https://auth.example.com/oauth/token'
# )

# Automatic token management:
# resp <- request('https://api.example.com/data') |>
#   req_oauth_client_credentials(client) |>
#   req_perform()
# httr2 automatically:
# 1. Gets access token using client credentials
# 2. Adds 'Authorization: Bearer <token>' header
# 3. Refreshes token when expired

cat('req_oauth_client_credentials() handles token lifecycle')
cat('Token is cached in memory automatically')

Kurzer Test

Testen Sie Ihr Verständnis beim Erstellen von REST-API-Clients in R mit httr2.

Zusammenfassung: REST-APIs verwenden

Wichtige Erkenntnisse: Erstellen Sie wiederverwendbare Clients, indem Sie Basis-URL, Authentifizierung und Wiederholungslogik in einem Konstruktor kapseln. Verwenden Sie req_auth_bearer_token() zur Authentifizierung und speichern Sie Token in Umgebungsvariablen. Behandeln Sie die Paginierung über Link-Header mit resp_link_url() oder über cursorbasierte Muster. Behandeln Sie HTTP-Fehler immer mit resp_check_status() und tryCatch(). Verwenden Sie req_perform_parallel() für Stapelverarbeitungen. Zwischenspeichern Sie Ergebnisse während der Entwicklung.

library(httr2)

# REST API client template:
make_api_call <- function(url, token,
                          method = 'GET',
                          body = NULL,
                          query = list()) {
  req <- request(url) |>
    req_method(method) |>
    req_auth_bearer_token(token) |>
    req_headers('Accept' = 'application/json') |>
    req_retry(max_tries = 3) |>
    req_throttle(rate = 10/60)
  if (length(query) > 0)
    req <- do.call(req_url_query, c(list(req), query))
  if (!is.null(body))
    req <- req |> req_body_json(body)
  req |> req_perform() |> resp_check_status()
}
cat('Template: auth + retry + throttle + error check')
Kostenlos starten

Lerne R mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
43
Lektionen
159

Häufig gestellte Fragen

Ist die Lektion „REST-APIs in R verwenden“ kostenlos?

Ja — der vollständige Text von „REST-APIs in R verwenden“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des R Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „REST-APIs in R verwenden“?

Authentifizieren Sie sich mit API-Schlüsseln, blättern Sie durch Ergebnisseiten und speichern Sie API-Antworten Du übst R Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um R Academy zu starten?

Keine Vorkenntnisse erforderlich. R Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „REST-APIs in R verwenden“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser R Academy-Lektion Code schreiben und ausführen?

Ja. Jede R Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. JSON mit jsonlite parsen
  2. HTTP-Anfragen mit httr2 senden
  3. REST-APIs in R verwenden
  4. Verschachtelte JSON-Strukturen verarbeiten
← Zurück zu R Academy