Consumo conjunto de APIs REST com curl e jq
Encadeie solicitações curl com jq para extrair, paginar e reformata respostas de APIs em tempo real nos scripts.
Consumo conjunto de APIs REST com curl e jq é uma aula grátis de DevOps Bootcamp no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de DevOps Bootcamp, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de DevOps Bootcamp inclui 4 aulas no total.
Por que curl + jq é uma combinação poderosa
APIs REST retornam JSON. O curl busca a resposta bruta; o jq a recorta, filtra e reorganiza — tudo em um único fluxo. Sem script Python, sem Postman e sem arquivo intermediário.
- curl lida com HTTP: métodos, cabeçalhos, autenticação e redirecionamentos.
- jq lida com JSON: filtragem, mapeamento, transformação e formatação.
- Conectá-los por pipe cria fluxos de trabalho de API concisos e combináveis.
Esta lição desenvolve essa habilidade desde os princípios básicos até padrões reais de paginação e criação de scripts.
Fluxo básico de curl para jq
O padrão mais simples: encaminhe a saída do curl diretamente para o jq. Use -s (silencioso) para suprimir o medidor de progresso do curl, fazendo com que apenas o corpo JSON chegue ao jq.
-s— modo silencioso, sem barra de progresso..— filtro de identidade do jq; exibe toda a resposta com formatação.-rno jq — saída bruta (sem aspas ao redor de strings).
#!/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'Configurando cabeçalhos de requisição e passando tokens de autenticação
A maioria das APIs de produção exige um cabeçalho Authorization ou uma chave de API. Passe cabeçalhos com -H e armazene segredos em variáveis de ambiente — nunca os codifique diretamente.
-H 'Authorization: Bearer $TOKEN'— injeta o cabeçalho de autenticação.-H 'Accept: application/json'— solicita explicitamente uma resposta JSON.- As variáveis são expandidas dentro de aspas duplas; use
"ao redor da string do cabeçalho.
#!/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}'Filtrando matrizes — .[] e select()
As APIs frequentemente retornam matrizes. Use .[] para iterar por cada elemento e, em seguida, select() para manter apenas os itens que correspondem a uma condição.
.[]— transforma uma matriz em um fluxo de objetos.select(.field == value)— mantém apenas os objetos correspondentes.- Encadeie vários filtros com
|.
#!/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'Extraindo vários campos com map()
map() aplica uma transformação a cada elemento de uma matriz e retorna uma nova matriz — equivalente a [.[] | ...], mas mais legível.
map({key: .field})— remodela cada objeto.- Combine com
@csvou@tsvpara produzir uma saída tabular. - Use
-rcom@csv/@tsvpara obter texto bruto (sem as aspas do 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'Padrão de paginação — repetir até obter uma página vazia
A maioria das APIs divide os resultados em páginas. Um padrão comum é usar um laço while que incrementa um contador de páginas e para quando a matriz retornada está vazia.
- Armazene a resposta do curl em uma variável com
$(curl ...). - Use
jq 'length'para verificar se a página contém itens. - Acumule os resultados com
jq -s(agregação) ou acrescente-os a um arquivo.
#!/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")"Paginação pelo cabeçalho Link (estilo GitHub)
GitHub e muitas outras APIs usam um cabeçalho de resposta Link para fornecer a URL da próxima página. É necessário analisar o cabeçalho em vez de tentar adivinhar a URL.
curl -iinclui os cabeçalhos de resposta na saída padrão; ou use-D -para despejar os cabeçalhos na saída padrão.- Analise o cabeçalho
Link: <url>; rel="next"comgrepesed. - Repita até que não haja um 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)"Encadeando solicitações — usando a saída de uma chamada como entrada para outra
Um fluxo de trabalho comum é buscar uma lista, extrair um ID e, em seguida, buscar os detalhes de cada ID. Armazene valores intermediários com a substituição de comandos $() e passe-os para a próxima URL.
- Extraia um único valor com
jq -r '.field'. - Percorra vários IDs com
jq -r '.[].id'dentro de um laçowhile read. - Use
sleepentre as solicitações para respeitar os limites de taxa.
#!/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
doneSolicitações POST — enviando cargas JSON
Para criar ou atualizar recursos, envie uma solicitação POST ou PUT com um corpo JSON. Use -X POST, -H 'Content-Type: application/json' e -d para o corpo. Construa a carga com jq -n para evitar problemas com aspas.
jq -n --arg key value '{key: $key}'— interpolação segura de variáveis no jq.- Envie o JSON construído diretamente para
-d @-do curl (lendo o corpo da entrada padrão). - Analise a resposta imediatamente com outro 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 '.'Tratamento de erros — códigos de status HTTP e erros de API
Uma conexão HTTP bem-sucedida não significa que a chamada à API foi bem-sucedida. Verifique separadamente o código de status HTTP e o campo de erro do JSON.
curl -w '%{http_code}'acrescenta o código de status à saída padrão; use-opara gravar o corpo em um arquivo.- Compare o código no seu script e trate os códigos 4xx/5xx de maneiras diferentes.
- Muitas APIs incluem
{"error": "..."}no corpo — verifique comhas()outypedo 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"Criando uma função auxiliar reutilizável para APIs
Coloque o código repetitivo de curl e verificação de erros em uma função do shell. A função cuida da autenticação, da verificação do status e da extração do JSON — quem a chama só precisa passar o endpoint e um filtro jq.
- Retorne códigos de saída diferentes de zero para erros HTTP, para que quem chama possa usar
||ouset -e. - Aceite um argumento de filtro jq para que a mesma função atenda a vários endpoints.
- Carregue este arquivo de função em qualquer script que precise da 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ção de conhecimento: estratégia de paginação
Teste sua compreensão sobre como tratar respostas paginadas de APIs REST em um script Bash usando curl e jq.
Revisão da lição: criação de scripts de API com curl + jq
Agora você tem um conjunto completo de ferramentas para consumir APIs REST pela linha de comando do Bash:
- Fluxo de processamento básico:
curl -s URL | jq 'filter'— a base de tudo. - Cabeçalhos de autenticação: passe tokens por meio de
-H, usando variáveis de ambiente, nunca valores codificados diretamente. - Manipulação de matrizes:
.[],select()emap()filtram e remodelam respostas de APIs. - Paginação: use um contador de páginas (com uma matriz vazia como indicador de parada) ou analise os cabeçalhos
Linkpara APIs cujo estilo fornece a URL seguinte. - Encadeamento: extraia IDs de uma resposta e use-os na próxima solicitação dentro de um laço
while read. - POST com cargas seguras: crie corpos JSON usando
jq -n --arge envie-os para-d @-do curl. - Tratamento de erros: separe o status HTTP (
-w '%{http_code}') dos erros da API presentes no corpo. - Auxiliar reutilizável: coloque o código repetitivo em uma função do shell para manter os scripts concisos e DRY.
Combine esses padrões e você poderá automatizar qualquer fluxo de trabalho de uma API JSON inteiramente pelo shell — sem precisar de um ambiente de execução adicional.
Perguntas Frequentes
A aula “Consumo conjunto de APIs REST com curl e jq” é grátis?
Sim — o texto completo de “Consumo conjunto de APIs REST com curl e jq” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de DevOps Bootcamp, atualize para CoddyKit PRO. O curso de DevOps Bootcamp inclui 4 aulas no total.
O que vou aprender em “Consumo conjunto de APIs REST com curl e jq”?
Encadeie solicitações curl com jq para extrair, paginar e reformata respostas de APIs em tempo real nos scripts. Você pratica DevOps Bootcamp com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar DevOps Bootcamp?
Nenhuma experiência prévia é necessária. DevOps Bootcamp no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Consumo conjunto de APIs REST com curl e jq”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de DevOps Bootcamp?
Sim. Cada aula de DevOps Bootcamp inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Filtragem e seleção de JSON com pipelines do jq
- Transformação e criação de objetos JSON com jq
- Consumo conjunto de APIs REST com curl e jq
- Edição de arquivos de configuração YAML com yq