jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Command Line cho Developer · Part 6 - Debug API with curl & jq

Debug HTTP API bằng terminal: curl GET/POST, headers, auth, status code, redirects, timeout, verbose mode, lưu response và jq để đọc/lọc JSON.

Đây là Phần 6. Khi app frontend báo lỗi API, đừng đoán ngay. Dùng curl để gọi endpoint trực tiếp và jq để đọc JSON.

Bạn cần trả lời nhanh:

  • API có reachable không?
  • Status code là gì?
  • Header có đúng không?
  • Body gửi lên có đúng shape không?
  • Response JSON có field mình cần không?

GET đơn giản

curl https://api.example.com/health

In cả header response:

curl -i https://api.example.com/health

Chỉ lấy header:

curl -I https://api.example.com/health

Follow redirect:

curl -L https://example.com

Thêm timeout:

curl --max-time 10 https://api.example.com/health

Nếu request treo mãi, timeout giúp bạn phân biệt server chậm với command đang chờ vô hạn.


Status code và fail mode

In status code cuối:

curl -s -o /tmp/response.json -w "%{http_code}\n" https://api.example.com/users

Giải thích:

FlagNghĩa
-ssilent, bớt progress noise
-o fileghi body vào file
-win thông tin sau request

Fail khi HTTP là 4xx/5xx:

curl --fail-with-body https://api.example.com/users

--fail-with-body hữu ích trong script: command trả non-zero khi HTTP lỗi nhưng vẫn giữ body lỗi để đọc.


Header và auth

Thêm header:

curl -H "Accept: application/json" https://api.example.com/users

Bearer token:

curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me

Gửi nhiều header:

curl \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  https://api.example.com/me

Không paste token thật vào shell history nếu đó là secret nhạy cảm. Ưu tiên biến môi trường tạm trong phiên shell, hoặc dùng secret manager của team.


POST JSON

curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice","role":"admin"}'

Với payload dài, để vào file:

cat > /tmp/user.json <<'JSON'
{
  "name": "Alice",
  "role": "admin"
}
JSON

curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  --data @/tmp/user.json

--data @file giúp payload review được, tái chạy được, và tránh quote JSON rối trên một dòng.


Verbose mode để debug network

curl -v https://api.example.com/health

-v cho thấy:

  • DNS/connect/TLS handshake;
  • request headers;
  • response headers;
  • redirect hoặc lỗi chứng chỉ.

Khi chỉ cần trace rất chi tiết:

curl --trace-ascii /tmp/curl.trace https://api.example.com/health

Đừng share trace nếu nó chứa token/cookie.


Pretty print JSON với jq

curl -s https://api.example.com/users | jq .

Lấy field:

curl -s https://api.example.com/me | jq '.email'
curl -s https://api.example.com/me | jq -r '.email'

-r in raw string, không có dấu quote.

Lọc array:

curl -s https://api.example.com/users |
jq '.users[] | {id, email, role}'

Chọn item:

curl -s https://api.example.com/users |
jq '.users[] | select(.role == "admin") | .email'

Đếm:

curl -s https://api.example.com/users | jq '.users | length'

Lưu response để phân tích

curl -s https://api.example.com/users -o /tmp/users.json
jq '.users | length' /tmp/users.json
jq '.users[] | select(.active == false)' /tmp/users.json

Khi response lớn, lưu file trước giúp bạn thử nhiều query jq mà không gọi API lặp lại.

So sánh response giữa staging và production:

curl -s https://staging.example.com/config | jq -S . > /tmp/staging.json
curl -s https://example.com/config | jq -S . > /tmp/prod.json
diff -u /tmp/staging.json /tmp/prod.json

jq -S sort key để diff ổn định hơn.


Recipe developer hay dùng

Health check local:

curl -i http://localhost:3000/health

Kiểm tra CORS preflight:

curl -i -X OPTIONS http://localhost:3000/api/users \
  -H "Origin: http://localhost:5173" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type,authorization"

Đo thời gian request:

curl -s -o /dev/null -w "status=%{http_code} time=%{time_total}s\n" \
  http://localhost:3000/api/users

Gửi form:

curl -X POST http://localhost:3000/login \
  -d "email=a@example.com" \
  -d "password=secret"

Upload file:

curl -X POST http://localhost:3000/upload \
  -F "file=@./avatar.png"

Bài tập

  1. Gọi một endpoint local hoặc public bằng curl -i.
  2. Lưu response JSON vào /tmp/response.json.
  3. Dùng jq lấy một field hoặc đếm số item trong array.
  4. Dùng curl -w in status code và total time.
Lời giải tham khảo
curl -i https://api.github.com/repos/withastro/astro
curl -s https://api.github.com/repos/withastro/astro -o /tmp/astro.json
jq -r '.full_name' /tmp/astro.json
curl -s -o /dev/null -w "status=%{http_code} time=%{time_total}s\n" \
  https://api.github.com/repos/withastro/astro

Điều cốt lõi

curl giúp bạn tách vấn đề API khỏi UI. jq giúp JSON đọc và lọc được. Khi bug HTTP xuất hiện, hãy gọi endpoint trực tiếp, xem status/header/body, rồi mới quay lại app.