使用 httr2 发起 HTTP 请求
发送 GET 和 POST 请求,处理标头并处理响应
使用 httr2 发起 HTTP 请求 是 CoddyKit 上的免费 R Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 R Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 R Academy 课程共包含 4 节课。
httr2 简介
httr2 是用于 HTTP 请求的现代 R 程序包,继承并改进了 httr。它采用基于管道的构建器模式:从 request(url) 开始,添加修饰函数,然后使用 req_perform() 执行。
library(httr2)
# Basic GET request pattern:
# request(url) -> create request object
# |> req_*() -> modify request
# |> req_perform() -> send request
# |> resp_*() -> extract from response
# Minimal example (requires internet):
# resp <- request('https://httpbin.org/get') |>
# req_perform()
# resp_status(resp) # 200
# resp_body_json(resp) # parsed JSON body
cat('httr2 follows: build -> perform -> extract')request() 和 req_perform()
request(url) 会创建请求对象。req_perform() 会执行请求并返回响应对象。随后可以使用 resp_* 函数检查响应。
library(httr2)
# Build and send a GET request
# resp <- request('https://httpbin.org/get') |>
# req_perform()
# Inspect response
# resp_status(resp) # 200
# resp_status_desc(resp) # 'OK'
# resp_headers(resp) # list of headers
# resp_header(resp, 'content-type') # single header
# resp_body_string(resp) # raw body as string
# resp_body_json(resp) # parsed JSON
# resp_body_raw(resp) # raw bytes
cat('Response hierarchy:')
cat('status -> headers -> body')req_headers():自定义标头
req_headers() 会添加或覆盖 HTTP 标头。它可用于身份验证令牌、内容类型声明、API 版本标头以及自定义请求元数据。
library(httr2)
# Add custom headers
# resp <- request('https://api.example.com/data') |>
# req_headers(
# 'Authorization' = 'Bearer my_token',
# 'X-API-Version' = '2',
# 'Accept' = 'application/json'
# ) |>
# req_perform()
# Common headers:
# 'Content-Type' = 'application/json' for POST with JSON body
# 'Accept' = 'application/json' to request JSON response
# 'User-Agent' = 'MyApp/1.0' for polite identification
# 'X-API-Key' = key for key-based auth
cat('req_headers() sets HTTP request headers')req_url_query():查询参数
req_url_query() 会安全地将查询参数追加到 URL(并对特殊字符进行编码)。这比手动使用 paste0() 拼接字符串更加简洁。
library(httr2)
# Add query parameters
# resp <- request('https://api.example.com/search') |>
# req_url_query(
# q = 'R programming',
# page = 1,
# size = 20,
# sort = 'relevance'
# ) |>
# req_perform()
# Resulting URL:
# https://api.example.com/search?q=R+programming&page=1&size=20&sort=relevance
# Inspect the URL without performing:
req <- request('https://api.example.com/search') |>
req_url_query(q = 'hello world', page = 2)
req$url
# 'https://api.example.com/search?q=hello+world&page=2'使用 req_body_json() 发送 POST 请求
使用 req_body_json() 在 POST 请求中发送 JSON 数据。它会自动设置 Content-Type: application/json 标头,并将 R 列表序列化为 JSON。
library(httr2)
# POST request with JSON body
# resp <- request('https://api.example.com/users') |>
# req_method('POST') |>
# req_body_json(list(
# name = 'Alice',
# email = 'alice@example.com',
# role = 'admin'
# )) |>
# req_perform()
# resp_status(resp) # 201 Created (if success)
# resp_body_json(resp) # returned user object
# Other body methods:
# req_body_form(...) -> application/x-www-form-urlencoded
# req_body_raw(bytes) -> raw bytes
# req_body_file(path) -> file upload
cat('req_body_json() handles Content-Type automatically')resp_body_json():解析响应
resp_body_json() 会将响应正文解析为 JSON,并转换为 R 列表。使用 simplifyVector=TRUE(默认值)可以自动将 JSON 数组转换为 R 向量,并将对象转换为带名称的列表。
library(httr2)
library(jsonlite)
# Simulated API response handling
# resp <- request('https://api.github.com/users/hadley') |>
# req_perform()
# user <- resp_body_json(resp)
# user$name # 'Hadley Wickham'
# user$public_repos # number of repos
# user$followers # follower count
# For arrays (simplifyVector=TRUE converts to data frame):
# resp <- request('https://api.github.com/users/hadley/repos') |>
# req_perform()
# repos <- resp_body_json(resp, simplifyVector = TRUE)
# repos$name # vector of repo names
cat('resp_body_json() with simplifyVector=TRUE -> data frame')resp_status() 和错误处理
resp_check_status() 会在响应状态为 4xx/5xx 时自动抛出错误。如果不使用它,httr2 不会因为错误的状态码而报错——您必须显式检查状态,或调用 resp_check_status()。
library(httr2)
# Pattern: check status after perform
# resp <- request('https://api.example.com/data') |>
# req_perform() |>
# resp_check_status() # errors on 4xx/5xx
# Manual status checks:
# status <- resp_status(resp)
# if (status == 200) { ... }
# if (status == 404) { stop('Not found') }
# if (status == 401) { stop('Unauthorized') }
# if (status == 429) { Sys.sleep(60); retry() }
# HTTP status codes:
# 200 OK, 201 Created, 204 No Content
# 400 Bad Request, 401 Unauthorized, 403 Forbidden
# 404 Not Found, 429 Rate Limited
# 500 Server Error, 503 Service Unavailable
cat('Always check response status codes')req_retry():自动重试
req_retry() 会自动重试失败的请求。请指定 max_tries,还可以选择指定 is_transient(用于识别可重试错误的函数,例如 429 或 503)。对于构建可靠的 API 客户端来说,这一点必不可少。
library(httr2)
# Automatic retry with exponential backoff
# resp <- request('https://api.example.com/data') |>
# req_retry(
# max_tries = 3,
# is_transient = function(resp) {
# resp_status(resp) %in% c(429, 500, 503)
# },
# backoff = ~ 2^.x # exponential: 2, 4, 8 seconds
# ) |>
# req_perform()
# Default retry behavior:
# - Retries on 429 Too Many Requests automatically
# - Uses Retry-After header if present
# - max_tries = 1 by default (no retry)
# Simple retry:
# req_retry(max_tries = 3) # retry up to 3 times total
cat('req_retry() adds resilience to API calls')req_throttle():速率限制
req_throttle(rate) 可确保请求速率不超过上限。请传入 rate = n/period(例如每分钟 10 个请求)。httr2 会根据需要在请求之间自动暂停。
library(httr2)
# Throttle to at most 10 requests per minute
# urls <- paste0('https://api.example.com/items/', 1:50)
# resps <- lapply(urls, function(url) {
# request(url) |>
# req_throttle(rate = 10 / 60) |> # 10/min
# req_perform()
# })
# Alternative: use req_perform_parallel() for parallel
# with throttle built in:
# reqs <- lapply(urls, \(u) request(u))
# resps <- req_perform_parallel(
# reqs,
# on_error = 'continue', # skip failures
# progress = TRUE
# )
cat('req_throttle(rate = 10/60) = 10 req/min')身份验证辅助函数
httr2 提供内置的身份验证辅助函数:req_auth_basic(user, pass) 用于基本身份验证,req_auth_bearer_token(token) 用于 Bearer 令牌,req_oauth_*() 用于 OAuth 流程。
library(httr2)
# Bearer token (most common for modern APIs)
# resp <- request('https://api.example.com/data') |>
# req_auth_bearer_token('my_api_token_here') |>
# req_perform()
# Basic authentication
# resp <- request('https://api.example.com/data') |>
# req_auth_basic('username', 'password') |>
# req_perform()
# Store tokens securely in environment variables
# token <- Sys.getenv('MY_API_TOKEN')
# resp <- request('https://api.example.com') |>
# req_auth_bearer_token(token) |>
# req_perform()
cat('Never hardcode tokens in scripts!')
cat('Use Sys.getenv() or the keyring package')使用 req_dry_run() 进行试运行
req_dry_run() 会准确显示将要发送的请求内容(方法、URL、标头和正文),但不会真正发送请求。在访问真实 API 之前调试复杂请求时,这一功能非常重要。
library(httr2)
# Inspect the request without sending it
req <- request('https://api.example.com/users') |>
req_method('POST') |>
req_headers(
'X-API-Version' = '2',
'Accept' = 'application/json'
) |>
req_auth_bearer_token('my_token') |>
req_body_json(list(name = 'Alice', role = 'admin')) |>
req_url_query(notify = 'true')
# Show request details without sending
req_dry_run(req)
# POST /users?notify=true HTTP/1.1
# Host: api.example.com
# Authorization: Bearer my_token
# Content-Type: application/json
# ...快速检查
测试您对 httr2 请求构建模式的理解。
回顾:使用 httr2 发送 HTTP 请求
要点: httr2 使用基于管道的构建器:request(url) |> req_*() |> req_perform()。使用 req_headers() 添加标头,使用 req_url_query() 添加查询参数,使用 req_body_json() 添加 JSON 正文。使用 req_auth_bearer_token() 进行身份验证。始终使用 resp_check_status() 检查状态。使用 req_retry() 增强容错能力,并使用 req_throttle() 限制速率。使用 req_dry_run() 进行调试。
library(httr2)
# Complete httr2 request pattern:
# resp <- request('https://api.example.com/endpoint') |>
# req_headers('Accept' = 'application/json') |>
# req_url_query(param1 = 'value', page = 1) |>
# req_auth_bearer_token(Sys.getenv('API_TOKEN')) |>
# req_retry(max_tries = 3) |>
# req_throttle(rate = 10/60) |>
# req_perform() |>
# resp_check_status()
# Extract data:
# data <- resp_body_json(resp, simplifyVector = TRUE)
cat('build -> authenticate -> perform -> check -> extract')常见问题解答
「使用 httr2 发起 HTTP 请求」课时是免费的吗?
是的 — 「使用 httr2 发起 HTTP 请求」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 R Academy 课程的其余内容,请升级到 CoddyKit PRO。 R Academy 课程共包含 4 节课。
「使用 httr2 发起 HTTP 请求」这节课中我会学到什么?
发送 GET 和 POST 请求,处理标头并处理响应 你通过在浏览器中直接运行的动手代码来练习 R Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 R Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 R Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 httr2 发起 HTTP 请求」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 R Academy 课中编写并运行代码吗?
能。每节 R Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 jsonlite 解析 JSON
- 使用 httr2 发起 HTTP 请求
- 在 R 中调用 REST API
- 处理嵌套 JSON 结构