httr2로 HTTP 요청 보내기
GET 및 POST 요청을 보내고, 헤더를 처리하며, 응답을 처리합니다.
httr2로 HTTP 요청 보내기은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 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를 지정하고, 429나 503처럼 재시도할 수 있는 오류를 식별하는 함수인 is_transient를 선택적으로 지정할 수 있습니다. 안정적인 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)는 Basic 인증에, 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 요청 보내기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“httr2로 HTTP 요청 보내기”에서 뭘 배우나요?
GET 및 POST 요청을 보내고, 헤더를 처리하며, 응답을 처리합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
R Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“httr2로 HTTP 요청 보내기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- jsonlite로 JSON 구문 분석
- httr2로 HTTP 요청 보내기
- R에서 REST API 사용하기
- 중첩된 JSON 구조 처리