Como Parsear JSON de API em Script Shell (Bash + Jq)

11 min de leitura Automação
Como Parsear JSON de API em Script Shell (Bash + Jq)

Introdução à Automação de APIs via Linha de Comando

No ambiente corporativo moderno, a integração entre sistemas é a espinha dorsal da infraestrutura de TI. Seja para monitorar o status de um serviço, coletar métricas de desempenho ou sincronizar dados entre plataformas, a capacidade de comunicar-se com APIs externas de forma eficiente é uma habilidade essencial para sysadmins e desenvolvedores. Embora linguagens como Python e Node.js sejam frequentemente escolhidas para essas tarefas devido à sua riqueza de bibliotecas, o script shell (Bash) oferece uma vantagem inegável: a ubiquidade.

A maioria dos servidores Linux já vem com as ferramentas necessárias pré-instaladas. Utilizar scripts em Bash para parsear JSON não apenas reduz a dependência de ambientes virtuais complexos ou instalações de pacotes desnecessários, mas também permite uma automação rápida e leve diretamente no terminal. Neste tutorial, vamos explorar como extrair, filtrar e processar dados estruturados provenientes de endpoints RESTful utilizando curl para a requisição HTTP e jq para a manipulação precisa do JSON.

A automação linux através de scripts shell é poderosa quando combinada com as ferramentas certas. Ao final deste guia, você será capaz de criar soluções robustas que consomem dados de qualquer API pública ou privada, transformando respostas complexas em informações acionáveis para seus sistemas.

Preparação do Ambiente e Instalação de Dependências

Antes de escrever o primeiro comando, é fundamental garantir que seu ambiente Linux possua as utilitários necessários. A estratégia padrão ouro para este processo envolve duas ferramentas principais:

  • curl: Uma ferramenta de transferência de dados com sintaxe URL e suporte a diversos protocolos (HTTP, HTTPS, FTP, etc.). É o padrão da indústria para fazer requisições HTTP em scripts.
  • jq: Um processador de linha de comando leve e flexível para JSON. Ele permite filtrar, mapear, transformar e formatar dados JSON de maneira eficiente.

Vamos verificar se o curl está instalado na sua máquina. Abra seu terminal e execute:

curl --version

Se a ferramenta retornar uma versão, você está pronto para a parte de rede. Caso contrário, instale-a usando o gerenciador de pacotes da sua distribuição. Para Debian/Ubuntu:

sudo apt update
sudo apt install curl

Para CentOS/RHEL/Fedora:

sudo yum install curl

Agora, o passo mais crítico: o jq. Diferente do curl, o jq nem sempre vem pré-instalado em servidores mínimos. Verifique a instalação com:

jq --version

Se o comando retornar "command not found", você precisará instalá-lo. Em ambientes Debian/Ubuntu:

sudo apt install jq

Em ambientes RHEL/CentOS:

sudo yum install jq

Com ambas as ferramentas disponíveis, seu ambiente está preparado para a integração API e o bash scripting.

Entendendo a Estrutura do JSON Retornado

Para parsear JSON corretamente, precisamos entender o que estamos recebendo. Vamos utilizar uma API pública de teste, a JSONPlaceholder, que retorna dados fictícios de usuários e posts.

Faça uma requisição GET simples para obter a lista dos cinco primeiros usuários:

curl -s https://jsonplaceholder.typicode.com/users?_limit=5

O sinalizador -s (silent) remove a barra de progresso do terminal, deixando apenas o corpo da resposta. O resultado será algo semelhante a:

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "[email protected]",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  ...
]

Note que o JSON é uma matriz de objetos. Cada objeto contém campos aninhados, como address.geo.lat. Sem o jq, extrair apenas a latitude do terceiro usuário exigiria o uso de expressões regulares complexas e frágeis com grep ou awk, que podem quebrar se a formatação do JSON mudar. O jq lida com a estrutura hierárquica de forma nativa.

Fazendo a Requisição HTTP com Curl

No contexto de automação linux, raramente queremos apenas ver o JSON no terminal; queremos processá-lo. O primeiro passo é garantir que a requisição curl seja feita corretamente, incluindo cabeçalhos (headers) se necessário.

Muitas APIs modernas exigem autenticação via token ou definem o tipo de conteúdo esperado. Vamos simular uma chamada que exige um cabeçalho de Autorização e aceita apenas JSON:

curl -s \
  -H "Accept: application/json" \
  -H "Authorization: Bearer SEU_TOKEN_AQUI" \
  https://api.exemplo.com/dados

Em um script real, é boa prática salvar a resposta em uma variável ou em um arquivo temporário para evitar múltiplas chamadas de rede desnecessárias. Isso melhora o desempenho e reduz a carga na API externa.

Exemplo 1: Salvando em variável

RESPONSE=$(curl -s https://jsonplaceholder.typicode.com/users/1)

Agora, a variável $RESPONSE contém o JSON inteiro. Para visualizar e verificar se funcionou:

echo "$RESPONSE"

Exemplo 2: Salvando em arquivo (útil para debugging)

curl -s https://jsonplaceholder.typicode.com/users/1 -o usuario.json

A partir daqui, aplicaremos o jq para transformar esses dados brutos em informação útil.

Domine o Parsear JSON com Jq: Comandos Essenciais

O jq funciona lendo JSON da entrada padrão (stdin) e escrevendo na saída padrão (stdout). Isso permite o uso de pipes (|) para encadear comandos, uma característica fundamental do script shell.

1. Extração Simples de Campos

Para obter o nome do usuário com ID 1:

echo "$RESPONSE" | jq '.name'

O resultado será "Leanne Graham". Note que o jq retorna a string entre aspas. Para remover as aspas e obter um texto puro (ideal para variáveis de shell), use a flag -r (raw output):

echo "$RESPONSE" | jq -r '.name'

Agora, o resultado é: Leanne Graham.

2. Acessando Objetos Aninhados

O JSON da API externa possui objetos dentro de objetos. Para acessar a cidade do endereço:

echo "$RESPONSE" | jq -r '.address.city'

O comando percorre a estrutura hierárquica até encontrar o valor desejado. Se você tentar acessar um campo inexistente, o jq retornará null, evitando erros fatais no script.

3. Trabalhando com Arrays (Listas)

Voltando ao exemplo inicial onde listamos 5 usuários, a resposta é um array. Para iterar sobre cada item e extrair apenas o email:

curl -s https://jsonplaceholder.typicode.com/users?_limit=5 | jq -r '.[].email'

O filtro .[] diz ao jq: "para cada elemento neste array, execute a operação seguinte". O resultado será uma lista vertical de emails.

4. Filtragem com Condicionais (Select)

Imagine que você quer apenas os usuários cujo nome começa com "S" ou cuja empresa tenha o termo "Crona" no nome. Use a função select:

curl -s https://jsonplaceholder.typicode.com/users | jq -r '.[] | select(.name | startswith("L")) | .name'

Este comando filtra o array, seleciona apenas os objetos onde o nome começa com "L" e retorna o nome formatado. Isso é extremamente poderoso para automação linux, permitindo que você tome decisões lógicas diretamente na extração de dados.

Criando um Script Shell Completo e Robusto

Agora vamos unir tudo em um script funcional. Este script demonstrará como realizar a integração API, tratar erros e formatar a saída para uso posterior (como log ou inserção em banco de dados).

Crie um arquivo chamado coleta_usuarios.sh:

#!/bin/bash

# Configurações
API_URL="https://jsonplaceholder.typicode.com/users"
OUTPUT_FILE="usuarios_extraidos.csv"
TEMP_JSON=$(mktemp)

echo "Iniciando coleta de dados da API externa..."

# 1. Faz a requisição e salva em arquivo temporário para evitar perda de dados se o curl falhar
curl -s -o "$TEMP_JSON" -w "%{http_code}" "$API_URL" > /dev/null

# Verifica o código de status HTTP retornado pelo curl (salvo na variável $? não funciona bem com -o, melhor usar -w)
# Vamos refazer para pegar o status code corretamente
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$API_URL")

if [ "$STATUS_CODE" -ne 200 ]; then
    echo "Erro: A API retornou o código de status $STATUS_CODE. Abortando."
    rm -f "$TEMP_JSON"
    exit 1
fi

# Rebaixar os dados novamente para processar (ou use a variável se já tivesse salvo)
curl -s "$API_URL" > "$TEMP_JSON"

echo "Dados recebidos. Processando JSON..."

# 2. Parseia o JSON e gera um CSV limpo
# Cabeçalho do CSV
echo "ID,NOME,EMAIL,CIDADE" > "$OUTPUT_FILE"

# Usa jq para extrair os campos específicos e formatar como CSV
jq -r '.[] | "\(.id),\(.name),\(.email),\(.address.city)"' "$TEMP_JSON" >> "$OUTPUT_FILE"

# 3. Limpeza
rm -f "$TEMP_JSON"

echo "Conclusão! Dados salvos em $OUTPUT_FILE"
cat "$OUTPUT_FILE"

Análise do script:

  • #!/bin/bash: Define o interpretador.
  • Mktemp: Cria um arquivo temporário seguro para armazenar o JSON bruto, isolando o processo de parseamento.
  • Tratamento de Erros: Verifica se a API respondeu com 200 OK. Se não, o script aborta, prevenindo processamento de dados inválidos.
  • Jq Format String: A sintaxe "\(.id),\(.name)" permite interpolar valores diretamente na string de saída, gerando um formato estruturado (CSV) pronto para importação em planilhas ou bancos de dados.

Torne o script executável e rode:

chmod +x coleta_usuarios.sh
./coleta_usuarios.sh

Boas Práticas e Segurança em Automação Linux

Ao implementar automação linux para consumo de APIs, considere os seguintes pontos críticos:

  1. Gestão de Segredos: Nunca hardcode tokens de API ou senhas no script. Use variáveis de ambiente ou arquivos de configuração protegidos (com permissão 600). Exemplo: TOKEN=$(cat /etc/secrets/api_token).
  2. Timeouts: Em scripts automatizados, uma requisição pendente pode travar seu processo. Sempre defina timeouts no curl. Use --max-time 10 para limitar a execução a 10 segundos.
  3. Retries (Retentativas): APIs externas podem falhar momentaneamente. Implemente um loop simples para tentar a requisição novamente em caso de falha de rede, mas com limites para evitar loops infinitos.
  4. Validação de Schema: Se possível, valide a estrutura do JSON recebido antes de processá-lo. O jq pode ser usado para verificar se campos obrigatórios existem.

Exemplo de loop com retry:

MAX_RETRIES=3
RETRY_COUNT=0

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
    RESPONSE=$(curl -s --max-time 5 "$API_URL")
    if [ $? -eq 0 ] && echo "$RESPONSE" | jq empty >/dev/null 2>&1; then
        break
    fi
    RETRY_COUNT=$((RETRY_COUNT + 1))
    sleep 2
done

if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
    echo "Falha ao obter dados após $MAX_RETRIES tentativas."
    exit 1
fi

Neste exemplo, jq empty verifica se a resposta é um JSON válido. Se não for (por exemplo, se o servidor retornou HTML de erro), o script tenta novamente.

Conclusão e Próximos Passos

A combinação de curl e jq em scripts shell é uma das ferramentas mais poderosas para profissionais de TI que buscam eficiência. Ela elimina a necessidade de ambientes pesados para tarefas simples de integração API, mantendo a infraestrutura leve e rápida.

Você aprendeu como:

  • Instalar e configurar as dependências necessárias em distribuições Linux principais.
  • Fazer requisições HTTP seguras e silenciosas.
  • Navegar em estruturas JSON complexas, incluindo objetos aninhados e arrays.
  • Filtrar dados usando condicionais e gerar formatos de saída estruturados (CSV).
  • Construir um script robusto com tratamento de erros e limpeza de arquivos temporários.

Para aprofundar seus conhecimentos em bash scripting, explore as funções avançadas do jq como map, reduce e group_by, que permitem transformar agregações complexas de dados diretamente no terminal. A automação linux continua sendo uma habilidade diferencial, e o domínio dessas ferramentas básicas é o primeiro passo para se tornar um administrador de sistemas ou DevOps altamente produtivo.

Compartilhar: Link copiado!
Esse tutorial foi útil?

Comentários (0)

Seja o primeiro a comentar.

Deixe seu comentário

Seu comentário será analisado antes de ser publicado.

0/2000