0Pricing
R Academy · 강의

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 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. jsonlite로 JSON 구문 분석
  2. httr2로 HTTP 요청 보내기
  3. R에서 REST API 사용하기
  4. 중첩된 JSON 구조 처리
← R Academy(으)로 돌아가기