การใช้ REST API ด้วย curl และ jq ร่วมกัน
เชื่อมคำขอ curl เข้ากับ jq เพื่อดึงข้อมูล แบ่งหน้า และจัดรูปแบบการตอบกลับ API แบบสดในสคริปต์
การใช้ REST API ด้วย curl และ jq ร่วมกัน เป็นบทเรียน DevOps Bootcamp ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน DevOps Bootcamp และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใด curl + jq จึงเป็นคู่หูทรงพลัง
REST API ส่งคืน JSON ส่วน curl ใช้ดึงการตอบกลับดิบ และ jq ใช้ตัด แบ่งกรอง และปรับรูปข้อมูล ทั้งหมดนี้ทำได้ในกระบวนการต่อเนื่องเดียว ไม่ต้องใช้สคริปต์ Python, Postman หรือไฟล์ชั่วคราว
- curl จัดการ HTTP ได้แก่ เมธอด ส่วนหัว การยืนยันตัวตน และการเปลี่ยนเส้นทาง
- jq จัดการ JSON ได้แก่ การกรอง การแมป การแปลง และการจัดรูปแบบ
- การส่งข้อมูลต่อระหว่างทั้งสองทำให้เกิดเวิร์กโฟลว์ API ที่กระชับและนำมาประกอบกันได้
บทเรียนนี้จะพัฒนาทักษะดังกล่าวตั้งแต่หลักการพื้นฐาน ไปจนถึงรูปแบบการแบ่งหน้าและการเขียนสคริปต์ที่ใช้จริง
กระบวนการต่อเนื่องพื้นฐานจาก curl ไปยัง jq
รูปแบบที่ง่ายที่สุดคือส่งเอาต์พุตของ curl ต่อเข้า jq โดยตรง ใช้ -s (ทำงานแบบเงียบ) เพื่อซ่อนมาตรวัดความคืบหน้าของ curl ทำให้มีเพียงเนื้อหา JSON เท่านั้นที่ส่งต่อไปยัง jq
-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จะรวมส่วนหัวการตอบกลับไว้ในเอาต์พุตมาตรฐาน หรือใช้-D -เพื่อส่งส่วนหัวออกไปยังเอาต์พุตมาตรฐาน- แยกวิเคราะห์ส่วนหัว
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)"การเชื่อมคำขอ — ใช้ผลลัพธ์จากการเรียกหนึ่งเป็นอินพุตของอีกการเรียก
ลำดับการทำงานที่ใช้กันทั่วไปคือ ดึงรายการออกมา ดึง ID ออกมา แล้วดึงรายละเอียดของแต่ละ ID เก็บค่าระหว่างทางด้วยการแทนที่คำสั่ง $() แล้วส่งค่าเหล่านั้นไปยัง URL ถัดไป
- ดึงค่าเดียวด้วย
jq -r '.field' - วนซ้ำกับ ID หลายค่าโดยใช้
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 (อ่านเนื้อหาจากอินพุตมาตรฐาน) - แยกวิเคราะห์การตอบกลับทันทีด้วยตัวกรอง 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}'จะต่อรหัสสถานะท้ายเอาต์พุตมาตรฐาน ใช้-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 และการตรวจสอบข้อผิดพลาดไว้ในฟังก์ชันของเชลล์ ฟังก์ชันนี้จัดการการยืนยันตัวตน การตรวจสอบสถานะ และการดึงข้อมูล JSON ส่วนผู้เรียกเพียงส่งปลายทางกับตัวกรอง jq
- ส่งคืนรหัสออกจากโปรแกรมที่ไม่ใช่ศูนย์เมื่อเกิดข้อผิดพลาด HTTP เพื่อให้ผู้เรียกใช้
||หรือset -eได้ - รับอาร์กิวเมนต์ตัวกรอง jq เพื่อให้ฟังก์ชันเดียวกันรองรับปลายทางได้หลายแบบ
- โหลดไฟล์ฟังก์ชันนี้จากสคริปต์ใด ๆ ที่ต้องใช้ 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 API จากบรรทัดคำสั่ง Bash แล้ว:
- ไปป์ไลน์พื้นฐาน:
curl -s URL | jq 'filter'— พื้นฐานของทุกอย่าง - ส่วนหัวการยืนยันตัวตน: ส่งโทเค็นผ่าน
-Hจากตัวแปรสภาพแวดล้อม อย่าเขียนค่าไว้ตายตัวในสคริปต์ - การจัดการอาร์เรย์:
.[],select()และmap()ใช้เลือกบางส่วนและปรับโครงสร้างการตอบกลับจาก API - การแบ่งหน้า: วนซ้ำด้วยตัวนับหน้า (ใช้ อาร์เรย์ว่างเป็นตัวบ่งชี้) หรือแยกวิเคราะห์ส่วนหัว
Linkสำหรับ API รูปแบบที่ระบุ URL หน้าถัดไป - การเชื่อมคำขอ: ดึง ID จากการตอบกลับหนึ่งครั้ง แล้วส่งต่อไปยังคำขอถัดไปภายในลูป
while read - POST พร้อมข้อมูลที่ปลอดภัย: สร้างเนื้อหา JSON ด้วย
jq -n --argแล้วส่งต่อไปยัง-d @-ของ curl - การจัดการข้อผิดพลาด: แยกสถานะ HTTP (
-w '%{http_code}') ออกจากข้อผิดพลาดระดับ API ในเนื้อหา - ตัวช่วยที่นำกลับมาใช้ซ้ำได้: รวมโค้ดมาตรฐานไว้ในฟังก์ชันของเชลล์ เพื่อให้สคริปต์กระชับและเป็นไปตาม DRY
เมื่อรวมรูปแบบเหล่านี้เข้าด้วยกัน คุณจะทำให้ลำดับงานของ JSON API ใด ๆ เป็นอัตโนมัติได้ทั้งหมดจากเชลล์ โดยไม่ต้องใช้สภาพแวดล้อมขณะทำงานเพิ่มเติม
คำถามที่พบบ่อย
บทเรียน “การใช้ REST API ด้วย curl และ jq ร่วมกัน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การใช้ REST API ด้วย curl และ jq ร่วมกัน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส DevOps Bootcamp ให้อัปเกรดเป็น CoddyKit PRO คอร์ส DevOps Bootcamp มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การใช้ REST API ด้วย curl และ jq ร่วมกัน”
เชื่อมคำขอ curl เข้ากับ jq เพื่อดึงข้อมูล แบ่งหน้า และจัดรูปแบบการตอบกลับ API แบบสดในสคริปต์ คุณปฏิบัติ DevOps Bootcamp ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน DevOps Bootcamp หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน DevOps Bootcamp บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การใช้ REST API ด้วย curl และ jq ร่วมกัน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน DevOps Bootcamp นี้ได้ไหม
ได้ บทเรียน DevOps Bootcamp ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกรองและเลือก JSON ด้วยไปป์ไลน์ jq
- การแปลงและสร้างออบเจกต์ JSON ด้วย jq
- การใช้ REST API ด้วย curl และ jq ร่วมกัน
- การแก้ไขไฟล์การกำหนดค่า YAML ด้วย yq