استهلاك REST APIs باستخدام curl وjq معًا
اربط طلبات curl ضمن jq لاستخراج استجابات API المباشرة وتقسيم صفحاتها وإعادة تنسيقها داخل السكربتات
استهلاك REST APIs باستخدام curl وjq معًا درس مجاني في DevOps Bootcamp على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في DevOps Bootcamp، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة DevOps Bootcamp 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 — من دون الحاجة إلى بيئة تشغيل إضافية.
تعلم DevOps Bootcamp مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 142
- الدروس
- 568
الأسئلة الشائعة
هل درس «استهلاك REST APIs باستخدام curl وjq معًا» مجاني؟
نعم — نص درس «استهلاك REST APIs باستخدام curl وjq معًا» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة DevOps Bootcamp، انتقل إلى CoddyKit PRO. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.
ماذا ستتعلم في «استهلاك REST APIs باستخدام curl وjq معًا»؟
اربط طلبات curl ضمن jq لاستخراج استجابات API المباشرة وتقسيم صفحاتها وإعادة تنسيقها داخل السكربتات تتمرن على DevOps Bootcamp مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ DevOps Bootcamp؟
لا تُشترط خبرة سابقة. DevOps Bootcamp على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «استهلاك REST APIs باستخدام curl وjq معًا»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس DevOps Bootcamp هذا؟
نعم. كل درس في DevOps Bootcamp يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تصفية JSON وتحديد عناصره باستخدام مسارات jq
- تحويل كائنات JSON وإنشاؤها باستخدام jq
- استهلاك REST APIs باستخدام curl وjq معًا
- تحرير ملفات إعداد YAML باستخدام yq