إجراء طلبات HTTP باستخدام httr2
أرسل طلبات GET وPOST، وتعامل مع الترويسات، وعالج الاستجابات
إجراء طلبات HTTP باستخدام httr2 درس مجاني في R Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.
مقدمة إلى httr2
إن httr2 حزمة R حديثة لإجراء طلبات HTTP، وقد جاءت خلفًا لـ 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'طلبات POST باستخدام req_body_json()
أرسل بيانات JSON في طلب POST باستخدام req_body_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.
مراجعة: طلبات HTTP باستخدام httr2
أهم النقاط: تستخدم httr2 مُنشئًا قائمًا على الأنابيب: request(url) |> req_*() |> req_perform(). أضف الرؤوس باستخدام req_headers()، ومعاملات الاستعلام باستخدام req_url_query()، وجسم JSON باستخدام req_body_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')الأسئلة الشائعة
هل درس «إجراء طلبات HTTP باستخدام httr2» مجاني؟
نعم — نص درس «إجراء طلبات HTTP باستخدام httr2» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.
ماذا ستتعلم في «إجراء طلبات HTTP باستخدام httr2»؟
أرسل طلبات GET وPOST، وتعامل مع الترويسات، وعالج الاستجابات تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟
لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «إجراء طلبات HTTP باستخدام httr2»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟
نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحليل JSON باستخدام jsonlite
- إجراء طلبات HTTP باستخدام httr2
- استهلاك REST APIs في R
- التعامل مع بنى JSON المتداخلة