0Pricing
Linux Command Line & Bash Scripting Mastery · درس

استهلاك REST APIs باستخدام curl وjq معًا

اربط طلبات curl ضمن jq لاستخراج استجابات API المباشرة وتقسيم صفحاتها وإعادة تنسيقها داخل السكربتات

استهلاك REST APIs باستخدام curl وjq معًا درس مجاني في Linux Command Line & Bash Scripting Mastery على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Linux Command Line & Bash Scripting Mastery، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.

لماذا يُعد الجمع بين curl و jq قويًا؟

تعيد REST APIs بيانات JSON. يجلب curl الاستجابة الخام؛ بينما يقتطعها jq ويصفيها ويعيد تشكيلها — وكل ذلك في مسار واحد. لا حاجة إلى نص Python أو Postman أو ملف وسيط.

  • يتولى curl HTTP: الأساليب والرؤوس والمصادقة وإعادة التوجيه.
  • يتولى jq JSON: التصفية والتعيين والتحويل والتنسيق.
  • يؤدي ربطهما بأنبوب إلى إنشاء مسارات عمل موجزة وقابلة للتركيب مع واجهات API.

يبني هذا الدرس هذه المهارة بدءًا من المبادئ الأساسية، وصولًا إلى أنماط الترحيل والبرمجة النصية الواقعية.

مسار curl أساسي إلى jq

أبسط نمط هو تمرير ناتج curl مباشرةً إلى jq. استخدموا -s (الوضع الصامت) لمنع عرض مقياس تقدم curl، بحيث لا يصل إلى jq سوى نص JSON.

  • -s — الوضع الصامت، من دون شريط تقدم.
  • . — عامل الهوية في jq؛ يعرض الاستجابة كاملةً بتنسيق منسق.
  • -r في jq — إخراج خام (من دون علامات اقتباس تحيط بالسلاسل النصية).
#!/usr/bin/env bash
# Fetch a public endpoint and pretty-print the JSON
curl -s 'https://jsonplaceholder.typicode.com/todos/1' | jq '.'

# Extract just the title field as a plain string
curl -s 'https://jsonplaceholder.typicode.com/todos/1' | jq -r '.title'

ضبط رؤوس الطلب وتمرير رموز المصادقة

تتطلب معظم واجهات API المستخدمة في بيئات الإنتاج رأس Authorization أو مفتاح API. مرروا الرؤوس باستخدام -H وخزنوا الأسرار في متغيرات البيئة — ولا تضعوها في الشيفرة مباشرةً.

  • -H 'Authorization: Bearer $TOKEN' — يحقن رأس المصادقة.
  • -H 'Accept: application/json' — يطلب صراحةً إعادة JSON.
  • تُوسَّع المتغيرات داخل علامات الاقتباس المزدوجة؛ استخدموا " حول سلسلة الرأس.
#!/usr/bin/env bash
TOKEN="${GITHUB_TOKEN}"   # set in your shell environment
USER="octocat"

curl -s \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/users/${USER}" \
| jq '{login: .login, repos: .public_repos, followers: .followers}'

تصفية المصفوفات — .[] و select()

تعيد واجهات API غالبًا مصفوفات. استخدموا .[] للمرور على كل عنصر، ثم select() للاحتفاظ بالعناصر المطابقة لشرط معين.

  • .[] — يحول المصفوفة إلى تدفق من الكائنات.
  • select(.field == value) — يحتفظ بالكائنات المطابقة فقط.
  • اربطوا عوامل التصفية المتعددة باستخدام |.
#!/usr/bin/env bash
# Fetch all todos and keep only the completed ones
curl -s 'https://jsonplaceholder.typicode.com/todos' \
| jq '[.[] | select(.completed == true) | {id, title}]'

# Count how many are completed
curl -s 'https://jsonplaceholder.typicode.com/todos' \
| jq '[.[] | select(.completed == true)] | length'

استخراج حقول متعددة باستخدام map()

تطبّق map() تحويلًا على كل عنصر في مصفوفة، ثم تُرجع مصفوفة جديدة — وهو ما يعادل [.[] | ...] لكنه أكثر وضوحًا.

  • map({key: .field}) — إعادة تشكيل كل كائن.
  • ادمجها مع @csv أو @tsv لإنتاج مخرجات جدولية.
  • استخدم -r مع @csv/@tsv للحصول على نص خام (من دون تنسيق JSON للعلامات).
#!/usr/bin/env bash
# Reshape a posts list into id + title pairs
curl -s 'https://jsonplaceholder.typicode.com/posts' \
| jq 'map({id, title: .title[0:40]})'

# Output as CSV for import into a spreadsheet
curl -s 'https://jsonplaceholder.typicode.com/posts' \
| jq -r '.[] | [.id, .userId, .title] | @csv'

نمط الترقيم — التكرار حتى ظهور صفحة فارغة

تُقسّم معظم واجهات API النتائج إلى صفحات. ومن الأنماط الشائعة استخدام حلقة while تزيد عدّاد الصفحة، وتتوقف عندما تكون المصفوفة المُرجعة فارغة.

  • خزّن استجابة curl في متغير باستخدام $(curl ...).
  • استخدم jq 'length' للتحقق مما إذا كانت الصفحة تحتوي على عناصر.
  • اجمع النتائج باستخدام jq -s (التحميل الكامل) أو ألحِقها بملف.
#!/usr/bin/env bash
# Paginate through jsonplaceholder posts (simulated: page stops at page 2
# because the API returns the full list regardless of ?_page, but the
# pattern is correct for real paginated APIs)

PAGE=1
PER_PAGE=10
OUTPUT="all_posts.json"
echo '[]' > "$OUTPUT"

while true; do
  RESPONSE=$(curl -s "https://jsonplaceholder.typicode.com/posts?_page=${PAGE}&_limit=${PER_PAGE}")
  COUNT=$(echo "$RESPONSE" | jq 'length')

  if [ "$COUNT" -eq 0 ]; then
    echo "No more pages. Stopping at page $((PAGE - 1))."
    break
  fi

  # Merge new items into the accumulated JSON array
  CURRENT=$(cat "$OUTPUT")
  echo "$CURRENT" "$RESPONSE" | jq -s '.[0] + .[1]' > "$OUTPUT"
  echo "Page $PAGE: fetched $COUNT items."
  PAGE=$((PAGE + 1))
done

echo "Total collected: $(jq 'length' "$OUTPUT")"

الترقيم باستخدام ترويسة Link (بنمط GitHub)

تستخدم GitHub والعديد من واجهات API الأخرى ترويسة الاستجابة Link لتوفير عنوان URL للصفحة التالية. يجب تحليل الترويسة بدلًا من تخمين عنوان URL.

  • تضمّن curl -i ترويسات الاستجابة في stdout؛ أو استخدم -D - لطباعة الترويسات إلى stdout.
  • حلّل ترويسة Link: <url>; rel="next" باستخدام grep وsed.
  • كرّر العملية حتى لا يعود رابط rel="next" موجودًا.
#!/usr/bin/env bash
# Follow Link-header pagination (GitHub repos example)
# Requires GITHUB_TOKEN in environment
TOKEN="${GITHUB_TOKEN}"
NEXT_URL="https://api.github.com/users/torvalds/repos?per_page=5"
ALL_REPOS="[]"

while [ -n "$NEXT_URL" ]; do
  # Capture full response (headers + body) to a temp file
  TMPFILE=$(mktemp)
  curl -sD "$TMPFILE" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "Accept: application/vnd.github+json" \
    "$NEXT_URL" \
  | {
      BODY=$(cat)
      ALL_REPOS=$(echo "$ALL_REPOS" "$BODY" | jq -s '.[0] + .[1]')
      echo "$ALL_REPOS" > /tmp/repos_acc.json
    }

  # Extract next URL from Link header
  NEXT_URL=$(grep -i '^link:' "$TMPFILE" \
    | sed -E 's/.*<([^>]+)>; rel="next".*/\1/;t;d')
  rm -f "$TMPFILE"
done

echo "Total repos: $(jq 'length' /tmp/repos_acc.json)"

تسلسل الطلبات — استخدام مخرجات طلب كمدخل لطلب آخر

من سير العمل الشائع: جلب قائمة، واستخراج معرّف، ثم جلب التفاصيل الخاصة بكل معرّف. خزّن القيم الوسيطة باستخدام استبدال الأوامر $()، ومرّرها إلى عنوان URL التالي.

  • استخرج قيمة واحدة باستخدام jq -r '.field'.
  • كرّر على عدة معرّفات باستخدام jq -r '.[].id' داخل حلقة while read.
  • استخدم sleep بين الطلبات للالتزام بحدود معدل الطلبات.
#!/usr/bin/env bash
# Step 1: get all user IDs from the /users endpoint
# Step 2: for each user, fetch their posts and count them

curl -s 'https://jsonplaceholder.typicode.com/users' \
| jq -r '.[].id' \
| while read -r USER_ID; do
    POST_COUNT=$(curl -s "https://jsonplaceholder.typicode.com/posts?userId=${USER_ID}" \
                 | jq 'length')
    echo "User ${USER_ID}: ${POST_COUNT} posts"
    sleep 0.1   # be polite to the API
done

طلبات POST — إرسال حمولات JSON

لإنشاء الموارد أو تحديثها، أرسل طلب POST أو PUT مع جسم بتنسيق JSON. استخدم -X POST و-H 'Content-Type: application/json' و-d للجسم. أنشئ الحمولة باستخدام jq -n لتجنب مشكلات الاقتباس.

  • jq -n --arg key value '{key: $key}' — استبدال آمن للمتغيرات في jq.
  • مرّر JSON المُنشأ مباشرةً إلى -d @- في curl (لقراءة الجسم من stdin).
  • حلّل الاستجابة فورًا باستخدام مرشح jq آخر.
#!/usr/bin/env bash
TITLE="My New Post"
BODY_TEXT="Written via curl and jq."
USER_ID=1

# Build the JSON payload safely and POST it
RESPONSE=$(jq -n \
  --arg title   "$TITLE" \
  --arg body    "$BODY_TEXT" \
  --argjson userId "$USER_ID" \
  '{title: $title, body: $body, userId: $userId}' \
| curl -s \
    -X POST \
    -H 'Content-Type: application/json' \
    -d @- \
    'https://jsonplaceholder.typicode.com/posts')

echo "Created post ID: $(echo "$RESPONSE" | jq '.id')"
echo "Full response:"
echo "$RESPONSE" | jq '.'

معالجة الأخطاء — رموز حالة HTTP وأخطاء API

لا يعني نجاح اتصال HTTP نجاح استدعاء API. تحقّق من رمز حالة HTTP ومن حقل خطأ JSON كلٌّ على حدة.

  • يُلحق curl -w '%{http_code}' رمز الحالة بـ stdout؛ استخدم -o لكتابة الجسم إلى ملف.
  • قارن الرمز في البرنامج النصي، وعالج أخطاء 4xx/5xx بطريقة مختلفة.
  • تضمّن العديد من واجهات API {"error": "..."} في الجسم — تحقّق منه باستخدام has() أو type في jq.
#!/usr/bin/env bash
API_URL='https://jsonplaceholder.typicode.com/todos/99999'
TMPBODY=$(mktemp)

HTTP_CODE=$(curl -s -o "$TMPBODY" -w '%{http_code}' "$API_URL")

if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
  echo "Success ($HTTP_CODE):"
  jq '.' "$TMPBODY"
elif [ "$HTTP_CODE" -eq 404 ]; then
  echo "Resource not found (404). Body:"
  jq '.' "$TMPBODY"
elif [ "$HTTP_CODE" -ge 500 ]; then
  echo "Server error ($HTTP_CODE). Retrying later."
else
  echo "Unexpected status: $HTTP_CODE"
  cat "$TMPBODY"
fi

rm -f "$TMPBODY"

إنشاء دالة مساعدة قابلة لإعادة الاستخدام لواجهة API

غلّف القالب البرمجي المتكرر الخاص بـ curl والتحقق من الأخطاء داخل دالة shell. تتولى الدالة المصادقة والتحقق من الحالة واستخراج JSON — ولا يحتاج المستدعي إلا إلى تمرير نقطة النهاية ومرشح jq.

  • أعِد رموز خروج غير صفرية عند حدوث أخطاء HTTP، حتى يتمكن المستدعون من استخدام || أو set -e.
  • اقبل وسيطًا لمرشح jq، حتى تخدم الدالة نفسها العديد من نقاط النهاية.
  • حمّل ملف هذه الدالة باستخدام source من أي برنامج نصي يحتاج إلى API.
#!/usr/bin/env bash
# api_get <endpoint_path> <jq_filter>
# Returns filtered JSON or exits non-zero on error.
api_get() {
  local PATH_PART="$1"
  local JQ_FILTER="${2:-.}"
  local BASE_URL='https://jsonplaceholder.typicode.com'
  local TMPBODY
  TMPBODY=$(mktemp)

  local HTTP_CODE
  HTTP_CODE=$(curl -s \
    -o "$TMPBODY" \
    -w '%{http_code}' \
    "${BASE_URL}${PATH_PART}")

  if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
    echo "[ERROR] HTTP $HTTP_CODE for ${PATH_PART}" >&2
    rm -f "$TMPBODY"
    return 1
  fi

  jq -r "$JQ_FILTER" "$TMPBODY"
  rm -f "$TMPBODY"
}

# Usage examples
api_get '/todos/1' '.title'
api_get '/posts?userId=1' '[.[] | .title]'
api_get '/users' '.[] | "\(.id) \(.name) <\(.email)>"'

اختبار المعرفة: استراتيجية الترقيم

اختبر مدى فهمك لكيفية التعامل مع استجابات REST API المُرقّمة في برنامج Bash النصي باستخدام curl وjq.

مراجعة الدرس: برمجة واجهات API باستخدام curl وjq

أصبح لديك الآن مجموعة أدوات متكاملة لاستهلاك REST APIs من سطر أوامر Bash:

  • الخط الأساسي: curl -s URL | jq 'filter' — الأساس الذي تُبنى عليه جميع العمليات.
  • ترويسات المصادقة: مرّر الرموز عبر -H من متغيرات البيئة، ولا تضعها في البرنامج النصي مباشرةً.
  • التعامل مع المصفوفات: تعمل .[] وselect() وmap() على تصفية استجابات API وإعادة تشكيلها.
  • الترقيم: استخدم حلقة مع عدّاد للصفحات (مع اعتبار المصفوفة الفارغة علامة توقف)، أو حلّل ترويسات Link لواجهات API التي توفر عنوان URL للصفحة التالية.
  • التسلسل: استخرج المعرّفات من استجابة، ثم مرّرها إلى الطلب التالي داخل حلقة while read.
  • POST بحمولات آمنة: أنشئ أجسام JSON باستخدام jq -n --arg ومرّرها إلى -d @- في curl.
  • معالجة الأخطاء: افصل حالة HTTP (-w '%{http_code}') عن الأخطاء على مستوى API الموجودة في الجسم.
  • دالة مساعدة قابلة لإعادة الاستخدام: غلّف القالب البرمجي المتكرر داخل دالة shell للحفاظ على إيجاز البرامج النصية وتجنب التكرار.

بدمج هذه الأنماط، يمكنك أتمتة أي سير عمل لواجهة JSON API بالكامل من shell — من دون الحاجة إلى بيئة تشغيل إضافية.

الأسئلة الشائعة

هل درس «استهلاك REST APIs باستخدام curl وjq معًا» مجاني؟

نعم — نص درس «استهلاك REST APIs باستخدام curl وjq معًا» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Linux Command Line & Bash Scripting Mastery، انتقل إلى CoddyKit PRO. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.

ماذا ستتعلم في «استهلاك REST APIs باستخدام curl وjq معًا»؟

اربط طلبات curl ضمن jq لاستخراج استجابات API المباشرة وتقسيم صفحاتها وإعادة تنسيقها داخل السكربتات تتمرن على Linux Command Line & Bash Scripting Mastery مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Linux Command Line & Bash Scripting Mastery؟

لا تُشترط خبرة سابقة. Linux Command Line & Bash Scripting Mastery على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «استهلاك REST APIs باستخدام curl وjq معًا»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Linux Command Line & Bash Scripting Mastery هذا؟

نعم. كل درس في Linux Command Line & Bash Scripting Mastery يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. تصفية JSON وتحديد عناصره باستخدام مسارات jq
  2. تحويل كائنات JSON وإنشاؤها باستخدام jq
  3. استهلاك REST APIs باستخدام curl وjq معًا
  4. تحرير ملفات إعداد YAML باستخدام yq
← العودة إلى Linux Command Line & Bash Scripting Mastery