0Pricing
DevOps Bootcamp · Aula

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.
  • -r no 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 @csv ou @tsv para produzir uma saída tabular.
  • Use -r com @csv/@tsv para 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 -i inclui 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" com grep e sed.
  • 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ço while read.
  • Use sleep entre 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
done

Solicitaçõ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 -o para 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 com has() ou type do 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 || ou set -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() e map() 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 Link para 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 --arg e 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

  1. Filtragem e seleção de JSON com pipelines do jq
  2. Transformação e criação de objetos JSON com jq
  3. Consumo conjunto de APIs REST com curl e jq
  4. Edição de arquivos de configuração YAML com yq
← Voltar para DevOps Bootcamp