Usare insieme curl e jq per consumare API REST
Concateni le richieste curl con jq per estrarre, impaginare e riformattare le risposte API in tempo reale negli script.
Usare insieme curl e jq per consumare API REST è una lezione DevOps Bootcamp gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento DevOps Bootcamp, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso DevOps Bootcamp include 4 lezioni in totale.
Perché curl + jq è la combinazione vincente
Le API REST restituiscono JSON. curl recupera la risposta grezza; jq la seleziona, filtra e ristruttura, tutto in un'unica pipeline. Non servono script Python, Postman o file intermedi.
- curl gestisce HTTP: metodi, intestazioni, autenticazione e reindirizzamenti.
- jq gestisce JSON: filtraggio, mapping, trasformazione e formattazione.
- Collegarli con una pipe crea flussi di lavoro API concisi e componibili.
Questa lezione sviluppa tale competenza partendo dai principi fondamentali e arrivando a schemi reali di paginazione e scripting.
Pipeline curl di base verso jq
Lo schema più semplice consiste nell'inviare direttamente l'output di curl a jq. Utilizzi -s (silent) per nascondere l'indicatore di avanzamento di curl, in modo che a jq arrivi solo il corpo JSON.
-s— modalità silenziosa, senza barra di avanzamento..— filtro identità di jq; formatta la risposta completa in modo leggibile.-rsu jq — output non elaborato, senza virgolette intorno alle stringhe.
#!/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'Impostare le intestazioni della richiesta e passare i token di autenticazione
La maggior parte delle API di produzione richiede un'intestazione Authorization o una chiave API. Passi le intestazioni con -H e conservi i segreti nelle variabili d'ambiente: non li inserisca mai direttamente nel codice.
-H 'Authorization: Bearer $TOKEN'— inserisce l'intestazione di autenticazione.-H 'Accept: application/json'— richiede esplicitamente una risposta JSON.- Le variabili vengono espanse tra virgolette doppie; utilizzi
"intorno alla stringa dell'intestazione.
#!/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}'Filtrare gli array — .[] e select()
Le API restituiscono spesso degli array. Utilizzi .[] per scorrere ogni elemento, quindi select() per mantenere solo gli elementi che corrispondono a una condizione.
.[]— espande un array in un flusso di oggetti.select(.field == value)— mantiene solo gli oggetti corrispondenti.- Concateni più filtri con
|.
#!/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'Estrazione di più campi con map()
map() applica una trasformazione a ogni elemento di un array e restituisce un nuovo array: è equivalente a [.[] | ...], ma più leggibile.
map({key: .field})— ristruttura ogni oggetto.- Combinatelo con
@csvo@tsvper produrre un output tabellare. - Usate
-rcon@csv/@tsvper ottenere testo non elaborato, senza virgolette 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'Schema per la paginazione: ciclo fino alla pagina vuota
La maggior parte delle API suddivide i risultati in pagine. Uno schema comune consiste in un ciclo while che incrementa un contatore di pagina e si interrompe quando l'array restituito è vuoto.
- Assegnate la risposta di curl a una variabile con
$(curl ...). - Usate
jq 'length'per verificare se la pagina contiene elementi. - Accumulate i risultati con
jq -s(slurp) oppure aggiungeteli a un file.
#!/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")"Paginazione con l'header Link (stile GitHub)
GitHub e molte altre API usano un header di risposta Link per fornire l'URL della pagina successiva. Dovete analizzare l'header invece di indovinare l'URL.
curl -iinclude gli header di risposta nello stdout; in alternativa, usate-D -per scaricare gli header nello stdout.- Analizzate l'header
Link: <url>; rel="next"congrepesed. - Continuate il ciclo finché non è presente alcun link
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)"concatenamento delle richieste: usare l'output di una chiamata come input per un'altra
Un flusso di lavoro comune consiste nel recuperare un elenco, estrarre un ID e quindi recuperare i dettagli per ogni ID. Memorizzate i valori intermedi con la sostituzione di comando $() e passateli all'URL successivo.
- Estraete un singolo valore con
jq -r '.field'. - Eseguite un ciclo su più ID con
jq -r '.[].id'all'interno di un ciclowhile read. - Usate
sleeptra le richieste per rispettare i limiti di frequenza.
#!/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
doneRichieste POST: invio di payload JSON
Per creare o aggiornare risorse, inviate una richiesta POST o PUT con un corpo JSON. Usate -X POST, -H 'Content-Type: application/json' e -d per il corpo. Create il payload con jq -n per evitare problemi con le virgolette.
jq -n --arg key value '{key: $key}'— interpolazione sicura delle variabili in jq.- Convogliate il JSON costruito direttamente nell'opzione
-d @-di curl (legge il corpo dallo stdin). - Analizzate immediatamente la risposta con un altro filtro 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 '.'Gestione degli errori: codici di stato HTTP ed errori API
Una connessione HTTP riuscita non significa che la chiamata API abbia avuto successo. Verificate separatamente il codice di stato HTTP e il campo di errore JSON.
curl -w '%{http_code}'aggiunge il codice di stato allo stdout; usate-oper scrivere il corpo in un file.- Confrontate il codice nello script e gestite diversamente gli errori 4xx/5xx.
- Molte API inseriscono nel corpo
{"error": "..."}: verificate la presenza del campo conhas()otypedi 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"Creazione di una funzione helper riutilizzabile per le API
Racchiudete il codice ripetitivo di curl e del controllo degli errori in una funzione shell. La funzione gestisce l'autenticazione, il controllo dello stato e l'estrazione JSON; chi la chiama deve solo passare l'endpoint e un filtro jq.
- Restituite codici di uscita diversi da zero in caso di errori HTTP, così chi chiama la funzione può usare
||oset -e. - Accettate un argomento per il filtro jq, in modo che la stessa funzione possa servire molti endpoint.
- Caricate il file della funzione da qualsiasi script che necessiti dell'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)>"'Verifica delle conoscenze: strategia di paginazione
Verificate la vostra comprensione della gestione delle risposte paginate delle API REST in uno script Bash usando curl e jq.
Riepilogo della lezione: scripting di API con curl + jq
Ora disponete di un toolkit completo per utilizzare le API REST dalla riga di comando Bash:
- Pipeline di base:
curl -s URL | jq 'filter'— la base di tutto. - Header di autenticazione: passate i token tramite
-Husando variabili d'ambiente, mai hardcoded. - Gestione degli array:
.[],select()emap()consentono di selezionare e ristrutturare le risposte API. - Paginazione: usate un ciclo con un contatore di pagina (sentinella dell'array vuoto) oppure analizzate gli header
Linkper le API che indicano l'URL successivo. - Concatenamento: estraete gli ID da una risposta e usateli nella richiesta successiva all'interno di un ciclo
while read. - POST con payload sicuri: create i corpi JSON usando
jq -n --arge convogliateli nell'opzione-d @-di curl. - Gestione degli errori: separate lo stato HTTP (
-w '%{http_code}') dagli errori a livello API presenti nel corpo. - Helper riutilizzabile: racchiudete il codice ripetitivo in una funzione shell, così gli script rimangono concisi e DRY.
Combinando questi schemi potete automatizzare qualsiasi flusso di lavoro con API JSON interamente dalla shell, senza bisogno di un runtime aggiuntivo.
Domande Frequenti
La lezione «Usare insieme curl e jq per consumare API REST» è gratuita?
Sì — il testo completo di «Usare insieme curl e jq per consumare API REST» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso DevOps Bootcamp, passa a CoddyKit PRO. Il corso DevOps Bootcamp include 4 lezioni in totale.
Cosa imparerò in «Usare insieme curl e jq per consumare API REST»?
Concateni le richieste curl con jq per estrarre, impaginare e riformattare le risposte API in tempo reale negli script. Eserciti DevOps Bootcamp con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare DevOps Bootcamp?
Non è richiesta alcuna esperienza precedente. DevOps Bootcamp su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Usare insieme curl e jq per consumare API REST»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione DevOps Bootcamp?
Sì. Ogni lezione DevOps Bootcamp include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Filtrare e selezionare JSON con le pipeline jq
- Trasformare e costruire oggetti JSON con jq
- Usare insieme curl e jq per consumare API REST
- Modificare file di configurazione YAML con yq