| Bellacosa Mainframe explora o json |
☕ Um Café no Bellacosa Mainframe
🕵️♂️ INSPETOR CLOUSEAU E O MISTÉRIO DAS CHAVES ENTRE CHAVES
JSON, APIs, arrays, objetos, jq, curl, Kubernetes, Terraform, CI/CD, observabilidade e o estranho caso do mainframe acusado de não saber conversar com o mundo moderno.
🎬 PRÓLOGO — Havia uma chave onde não deveria haver uma chave
Paris, algum momento entre um incidente de produção e uma reunião que deveria ter sido um e-mail.
O telefone toca.
— Inspetor Clouseau? Temos um problema.
Clouseau ajeita o sobretudo.
— Naturalmente. Se não houvesse problema, não estariam ligando para o maior detetive da França.
— Uma aplicação parou de funcionar.
— Sabotage!
— Não sabemos.
— Ransomware!
— Também não.
— Mainframe!
Silêncio.
Do outro lado da linha, alguém respira fundo.
— Inspetor... o erro diz:
Unexpected token } in JSONClouseau estreita os olhos.
— Aha! Então temos um suspeito.
Ele pega a lupa.
Na tela aparece:
{
"customer": "Bellacosa",
"status": "ACTIVE",
}Clouseau observa durante vários segundos.
— Onde está o criminoso?
O programador aponta.
"ACTIVE",
^Uma vírgula.
Uma pequena vírgula.
Um caractere com poucos pixels havia derrubado uma automação inteira.
E assim começava uma investigação que levaria Clouseau por APIs, pipelines, Kubernetes, Terraform, logs, curl, jq e finalmente até um velho programa COBOL que, como quase sempre acontece nessas histórias, estava sendo acusado injustamente.
Porque o verdadeiro mistério não era:
“O que é JSON?”
Era muito maior:
Como sistemas completamente diferentes conseguem conversar sem precisar conhecer a implementação interna uns dos outros?
E essa pergunta nos leva diretamente ao coração da computação moderna.
🕵️ CAPÍTULO 1 — O primeiro suspeito: JSON
JSON significa JavaScript Object Notation.
Mas esse nome frequentemente provoca o primeiro erro conceitual.
JSON não é JavaScript.
Também não é uma linguagem de programação.
Não possui IF, PERFORM, métodos, classes ou algoritmos.
JSON é essencialmente uma representação textual de dados estruturados.
A especificação padronizada pela IETF, RFC 8259, define JSON como um formato textual e independente de linguagem para intercâmbio de dados estruturados. Ela estabelece quatro tipos primitivos — string, number, boolean e null — além de dois tipos estruturados: object e array.
Clouseau imediatamente faz uma anotação:
SUSPEITO: JSON
CRIME: transportar dados
ARMA: { }
CÚMPLICE: [ ]Mas transportar dados não parece exatamente um crime.
Na verdade, essa simplicidade explica boa parte do sucesso do JSON.
Imagine:
{
"name": "Vagner",
"technology": "COBOL",
"experience": 35,
"active": true
}Não existe programa sendo executado ali.
Existe apenas uma afirmação estruturada sobre dados.
🧱 CAPÍTULO 2 — Clouseau encontra um COPYBOOK disfarçado
Para quem vem do COBOL, talvez exista uma maneira muito melhor de entender JSON do que começar falando de JavaScript.
Imagine:
01 CUSTOMER.
05 CUSTOMER-ID PIC 9(8).
05 CUSTOMER-NAME PIC X(40).
05 CUSTOMER-STATUS PIC X(10).
05 CUSTOMER-BALANCE PIC S9(9)V99 COMP-3.O programador mainframe olha para isso e imediatamente enxerga uma estrutura.
Existe um grupo.
Dentro dele existem campos.
Cada campo possui significado, tamanho e representação.
Agora imagine uma representação conceitualmente equivalente:
{
"customerId": 12345678,
"customerName": "BELLACOSA",
"customerStatus": "ACTIVE",
"customerBalance": 15872.35
}Clouseau olha para o COPYBOOK.
Olha para o JSON.
Olha novamente para o COPYBOOK.
— São irmãos!
Não exatamente.
Mas a intuição é excelente.
O COPYBOOK descreve uma estrutura muito mais rígida: posição, tamanho, representação numérica, agrupamento etc.
JSON trabalha de outra maneira:
"customerName" : "BELLACOSA"
│ │
│ └── valor
│
└── chaveEm vez de perguntar:
“Em qual posição começa esse campo?”
perguntamos:
“Qual é o valor associado a esta chave?”
Essa diferença parece pequena.
Arquitetonicamente, é gigantesca.
🔑 CAPÍTULO 3 — O estranho caso das chaves
Um objeto JSON utiliza:
{
}E contém pares:
chave : valorPor exemplo:
{
"system": "CICS",
"region": "CICSPRD1",
"status": "UP"
}A RFC especifica objetos como coleções de pares nome/valor e recomenda que os nomes sejam únicos. Também é importante não construir aplicações que dependam da ordem das propriedades de um objeto.
Isso produz uma diferença interessante em relação ao pensamento tradicional de registros posicionais.
Em:
BELLACOSA 000001 ACTIVEo significado depende fortemente da convenção sobre onde cada informação está.
Em:
{
"name": "BELLACOSA",
"id": 1,
"status": "ACTIVE"
}parte do significado acompanha o próprio dado.
O formato ficou mais verboso.
Mas também muito mais autodescritivo.
Clouseau imediatamente conclui:
— Então quanto maior o arquivo, melhor!
Não, Clouseau.
Continue investigando.
📦 CAPÍTULO 4 — Os cúmplices chamados Arrays
Então aparece:
[
]Se {} representa um objeto, [] representa um array.
Por exemplo:
{
"regions": [
"CICSPRD1",
"CICSPRD2",
"CICSTST1"
]
}A RFC define arrays como sequências ordenadas de valores.
Para um programador COBOL, existe uma associação mental extremamente útil:
05 TRANSACTION OCCURS 100 TIMES.Não significa que OCCURS e JSON Array sejam tecnicamente a mesma coisa.
Não são.
Mas ambos representam a ideia fundamental:
há múltiplas ocorrências de alguma coisa.
Podemos ter objetos dentro do array:
{
"regions": [
{
"name": "CICSPRD1",
"status": "UP"
},
{
"name": "CICSPRD2",
"status": "DOWN"
}
]
}Agora nossa estrutura começa a ficar interessante.
🪆 CAPÍTULO 5 — Clouseau descobre objetos dentro de objetos
Então surge o verdadeiro terror do iniciante:
{
"customer": {
"id": 12345,
"accounts": [
{
"type": "CHECKING",
"balance": 1500.25
},
{
"type": "SAVINGS",
"balance": 8700.00
}
]
}
}Clouseau olha para aquilo.
— Mon Dieu. Alguém colocou um JSON dentro do JSON.
Sim.
E pode colocar outro.
E outro.
Porque JSON forma naturalmente uma árvore.
customer
│
├── id
│
└── accounts
│
├── [0]
│ ├── type
│ └── balance
│
└── [1]
├── type
└── balanceE isso muda completamente a maneira de ler estruturas grandes.
Em vez de tentar compreender cinquenta linhas simultaneamente, seguimos um caminho:
customer
↓
accounts
↓
[0]
↓
balanceMentalmente:
customer.accounts[0].balanceQuem trabalhou com estruturas hierárquicas, IMS ou grupos COBOL talvez perceba algo curioso.
Essa maneira de pensar não é tão alienígena quanto parece.
O vocabulário mudou.
A árvore não.
🧬 CAPÍTULO 6 — JSON tem tipos, mas Clouseau quase perdeu essa pista
Observe:
{
"name": "Bellacosa",
"age": 52,
"active": true,
"error": null
}Temos:
"Bellacosa" → string
52 → number
true → boolean
null → nullAlém deles existem:
{} → object
[] → arrayIsso é muito importante.
Veja:
{
"cpu": 90
}e:
{
"cpu": "90"
}Visualmente parecem quase iguais.
Semanticamente não são.
No primeiro:
90 = númeroNo segundo:
"90" = textoE agora aparece um problema particularmente interessante para quem vem de COBOL.
💰 CAPÍTULO 7 — O mistério do dinheiro desaparecido
No COBOL podemos escrever:
05 BALANCE PIC S9(11)V99 COMP-3.Isso diz muita coisa.
JSON simplesmente oferece:
{
"balance": 123456789.99
}Mas qual precisão deve ser utilizada?
Qual representação interna?
Qual escala?
O consumidor usa double?
decimal?
BigDecimal?
A própria RFC permite que implementações imponham limites de precisão e intervalo aos números JSON. (RFC Editor)
Agora Clouseau encontrou uma pista realmente importante.
Quando atravessamos fronteiras tecnológicas:
COBOL COMP-3
↓
JSON number
↓
Java / JavaScript / Python
↓
Banco de dadosprecisamos pensar cuidadosamente em precisão.
Especialmente para:
dinheiro
identificadores gigantes
timestamps
medições científicas
números com precisão decimal obrigatóriaÀs vezes uma API deliberadamente envia determinados valores como strings:
{
"amount": "123456789.99"
}e define no contrato como interpretá-los.
Não porque JSON esteja quebrado.
Mas porque interoperabilidade também significa preservar significado.
👻 CAPÍTULO 8 — Null não significa desaparecido
Clouseau encontra dois arquivos.
Arquivo A:
{}Arquivo B:
{
"telephone": null
}— São iguais!
Não necessariamente.
No primeiro:
a propriedade não existe.
No segundo:
a propriedade existe e seu valor é
null.
Essa distinção pode ser crucial em APIs.
Imagine uma operação de atualização.
{
"telephone": null
}poderia significar:
remova o telefone.
Enquanto:
{}poderia significar:
não altere o telefone.
Isso depende do contrato da API, mas demonstra uma lição muito maior:
Sintaxe não determina sozinha a semântica.
E essa frase vai voltar à nossa investigação.
🚨 CAPÍTULO 9 — O JSON era válido. O sistema caiu mesmo assim
Imagine:
{
"customerId": 123,
"withdrawal": 999999999
}Perfeitamente válido como JSON.
Mas o cliente possui:
Saldo = R$ 27,50Portanto existem diferentes níveis de validade:
SINTAXE
↓
ESTRUTURA / SCHEMA
↓
SEMÂNTICA
↓
REGRA DE NEGÓCIOUm documento pode ser sintaticamente perfeito e ainda assim estar completamente errado para aquela aplicação.
Clouseau começa a compreender que seu erro inicial foi perguntar:
“O JSON está correto?”
A pergunta certa seria:
“Correto em qual camada?”
Isso é uma extraordinária pergunta para troubleshooting.
🌐 CAPÍTULO 10 — O JSON sai de casa e encontra uma API
Agora chegamos ao ponto em que JSON conquistou grande parte do mundo moderno.
Imagine:
Aplicação
│
│ HTTP Request
▼
┌───────────────┐
│ API │
└───────────────┘
│
│ HTTP Response
▼
AplicaçãoO corpo pode conter:
{
"customer": 12345,
"status": "ACTIVE"
}Mas aqui Clouseau comete outro erro.
— HTTP é JSON!
Não.
HTTP é o protocolo.
JSON pode ser o formato do conteúdo transportado.
Também não devemos transformar:
REST = JSONem identidade matemática.
Podemos ter APIs utilizando outros formatos.
A distinção conceitual é importantíssima:
HTTP
├── status
├── headers
└── body
└── talvez JSONUm:
HTTP 500é uma informação sobre a interação HTTP.
Um:
{
"error": "database unavailable"
}é conteúdo.
Misturar essas camadas torna troubleshooting muito mais difícil.
🔦 CAPÍTULO 11 — Clouseau encontra o curl
Precisamos investigar uma API.
Entra em cena:
curlPor exemplo:
curl https://api.example.com/customers/123A resposta:
{
"id": 123,
"name": "Bellacosa",
"status": "ACTIVE"
}Agora conseguimos interrogar diretamente a API.
Mas uma resposta real pode possuir milhares de linhas.
Clouseau pega sua lupa.
Existe uma ferramenta melhor.
🔬 CAPÍTULO 12 — jq: a lupa do detetive DevOps
Entra:
jqSe tivermos:
{
"customer": {
"name": "Bellacosa",
"accounts": [
{
"type": "CHECKING",
"balance": 1500
},
{
"type": "SAVINGS",
"balance": 8700
}
]
}
}podemos perguntar:
jq '.customer.name'Resultado:
"Bellacosa"Ou:
jq '.customer.accounts[0].balance'Resultado:
1500Ou ainda:
jq '.customer.accounts[].balance'Resultado:
1500
8700Mas aqui está o salto conceitual.
jq não é apenas um pretty printer.
Ele permite consultar, selecionar e transformar árvores JSON.
Imagine:
curl -s https://api.example.com/accounts |
jq '.accounts[] | select(.balance > 5000)'Agora temos uma pequena investigação automatizada:
API
↓
curl
↓
JSON
↓
jq
↓
filtro
↓
informaçãoÉ quase um SQL para a árvore JSON — não literalmente, mas é uma excelente analogia mental inicial.
☸️ CAPÍTULO 13 — O crime chega ao Kubernetes
Clouseau entra em uma sala cheia de YAML.
— Finalmente escapamos do JSON.
Não exatamente.
YAML e JSON aparecem frequentemente em papéis complementares nesse ecossistema.
Quando observamos objetos Kubernetes, três regiões são particularmente interessantes:
metadata
spec
statusUma forma conceitual de enxergá-las:
metadata → quem sou eu?
spec → como desejo que eu esteja?
status → como estou agora?E aqui aparece algo muito mais importante do que aprender chaves e colchetes.
A ideia de desired state.
Você declara:
quero 3 réplicasO sistema observa:
existem 2E tenta reconciliar:
DESEJADO
│
▼
┌──────────────┐
│ RECONCILIAÇÃO│
└──────────────┘
│
▼
ATUALIsso é arquitetura.
JSON é apenas uma das formas pelas quais podemos observar ou transportar essa representação.
🏗️ CAPÍTULO 14 — Terraform entra na delegacia
Clouseau encontra outro arquivo.
Agora temos infraestrutura descrita e administrada de forma declarativa.
Terraform consegue produzir representações JSON de plans e state com:
terraform show -jsonA documentação oficial descreve essa saída como uma representação legível por máquinas do plano ou estado, justamente para permitir processamento automatizado. (HashiCorp Developer)
Isso possibilita:
Terraform
↓
JSON
↓
jq / programa
↓
policy
↓
pipelinePor exemplo, conceitualmente:
terraform show -json plan.tfplan |
jq '.resource_changes[]'De repente JSON deixou de ser apenas “arquivo de configuração”.
Virou uma interface entre ferramentas.
Mas há uma pista de segurança importante: a HashiCorp alerta que terraform show -json pode revelar valores sensíveis do state em texto claro. (HashiCorp Developer)
Portanto:
JSON + automação ≠ automaticamente seguro🏭 CAPÍTULO 15 — O JSON invade o CI/CD
Imagine uma pipeline:
SOURCE
↓
BUILD
↓
TEST
↓
PACKAGE
↓
DEPLOY
↓
MONITORCada etapa precisa comunicar informações.
Build:
{
"buildId": 8731,
"status": "SUCCESS"
}Teste:
{
"tests": 428,
"passed": 427,
"failed": 1
}Deployment:
{
"environment": "PRODUCTION",
"version": "4.17.2",
"status": "DEPLOYED"
}Perceba o padrão.
JSON começa a funcionar como um envelope universal de metadados.
Ferramenta A não precisa conhecer toda a implementação de B.
Precisa conhecer o contrato.
E aqui chegamos ao verdadeiro personagem principal desta história.
Não é JSON.
É o contrato.
📜 CAPÍTULO 16 — O verdadeiro suspeito era o contrato
Considere:
{
"customerId": 12345
}Um desenvolvedor decide melhorar o nome:
{
"customer_id": 12345
}Ambos são JSON perfeitamente válidos.
Mas o consumidor procura:
customerIdResultado:
NULL
ERROR
FAILED
ABEND
PIPELINE BROKENClouseau grita:
— JSON defeituoso!
Não.
O JSON está perfeito.
O contrato foi quebrado.
Esse problema nos leva a:
versionamento
schema
compatibilidade
contract testing
governança
backward compatibilityE isso explica por que simplesmente dizer “usamos JSON” quase não nos diz nada sobre a maturidade de uma arquitetura.
🧾 CAPÍTULO 17 — COPYBOOK encontra JSON Schema
Aqui surge uma comparação extremamente interessante para o mundo mainframe.
COPYBOOK:
05 CUSTOMER-ID PIC 9(8).JSON:
{
"customerId": 12345678
}O JSON isoladamente diz pouco sobre as restrições do campo.
Um schema pode estabelecer expectativas muito mais detalhadas.
Assim aparece uma associação conceitual:
COPYBOOK
│
├── estrutura
├── tipos
└── contratoe:
JSON
+
JSON Schema
│
├── estrutura
├── tipos
└── contratoEles não são equivalentes tecnicamente.
Mas a comparação é pedagogicamente poderosa.
O veterano COBOL descobre então uma coisa divertida:
O mundo distribuído passou décadas reinventando maneiras de dizer:
“Este dado precisa obedecer a um layout.”
Clouseau sorri.
O mainframe também.
📡 CAPÍTULO 18 — O COBOL finalmente aparece
Agora chegamos à vítima injustamente acusada.
Temos:
Mobile
Web
Cloud
Parceiros
Microsserviços
│
▼
REST
│
▼
JSON
│
▼
z/OS Connect
│
▼
CICS
│
▼
COBOL
│
▼
Db2 / VSAM / IMSE alguém diz:
“Transformamos COBOL em JSON.”
Não exatamente.
COBOL continua COBOL.
CICS continua CICS.
Db2 continua Db2.
O que criamos é uma fronteira de representação.
Externamente:
{
"account": "123456",
"balance": 7500.25
}Internamente podemos ter algo semelhante a:
01 ACCOUNT-DATA.
05 ACCOUNT-NUMBER PIC X(6).
05 ACCOUNT-BALANCE PIC S9(7)V99 COMP-3.Existe então uma transformação:
REPRESENTAÇÃO EXTERNA
↕
MAPEAMENTO
↕
REPRESENTAÇÃO INTERNAEssa ideia é fundamental para modernização de mainframe.
Modernizar não exige necessariamente destruir aquilo que funciona.
Às vezes significa simplesmente oferecer novas interfaces para capacidades existentes.
📟 CAPÍTULO 19 — O incidente das 03:17
São 03:17.
Naturalmente.
Um alerta chega:
{
"timestamp": "2026-09-17T03:17:42Z",
"service": "payment-api",
"severity": "critical",
"transaction": "PAYMENT",
"backend": "CICS",
"responseTime": 8421,
"status": "timeout"
}Há algumas décadas talvez tivéssemos:
20260917031742 PAYAPI CRIT PAY CICS 8421 TIMEOUTPerfeitamente processável.
Mas agora cada informação possui identidade explícita.
Isso facilita:
indexação
correlação
pesquisa
dashboards
alertas
automação
machine learning
IAImagine milhões desses eventos.
Podemos perguntar:
Mostre severity=critical
onde backend=CICS
e responseTime > 5000
nas últimas duas horas.Essa é uma das razões pelas quais structured logging tornou-se tão poderoso.
JSON não é somente intercâmbio de APIs.
Pode ser também a matéria-prima da observabilidade.
🔥 CAPÍTULO 20 — Clouseau encontra um JSON quebrado
Finalmente chega o incidente clássico:
parse errorO arquivo:
{
"system": "CICS"
"status": "UP"
}Clouseau investiga Kubernetes.
Nada.
Investiga RACF.
Nada.
Investiga Db2.
Nada.
Investiga TCP/IP.
Nada.
Quatro horas depois alguém percebe:
{
"system": "CICS",
↑
"status": "UP"
}Faltava uma vírgula.
JSON possui uma gramática pequena, mas rígida. Strings e nomes usam aspas duplas; objetos usam {}, arrays usam []; os literais são true, false e null em minúsculas.
Uma boa investigação segue:
ERROR
↓
VALIDATE
↓
LOCATE
↓
FIX
↓
RE-RUN
↓
VERIFYNão:
ERROR
↓
ALTERA 17 COISAS
↓
RESTART
↓
REZAEmbora Clouseau prefira o segundo método.
🧠 CAPÍTULO 21 — O programador COBOL percebe que já conhecia metade disso
Depois de horas de investigação, Clouseau reúne todos na biblioteca.
Como todo bom detetive.
Na parede:
COPYBOOK
↓
ESTRUTURA
JSON
↓
REPRESENTAÇÃO
JSON SCHEMA
↓
CONTRATO
HTTP / REST
↓
COMUNICAÇÃO
curl
↓
CLIENTE / INVESTIGAÇÃO
jq
↓
CONSULTA / TRANSFORMAÇÃO
KUBERNETES
↓
ESTADO DESEJADO
TERRAFORM
↓
INFRAESTRUTURA DECLARATIVA + ESTADO
CI/CD
↓
AUTOMAÇÃO
OBSERVABILIDADE
↓
TELEMETRIA E INVESTIGAÇÃOEntão vem a revelação.
Para alguém com décadas de mainframe, boa parte dos conceitos fundamentais não é nova.
Já conhecíamos:
campos
registros
grupos
ocorrências
layouts
contratos
interfaces
serialização
validação
mensagens
transações
logs
monitoramentoMudaram as ferramentas.
Mudaram as representações.
Mudou o ecossistema.
Mas muitos problemas fundamentais permaneceram.
🕵️♂️ EPÍLOGO — Clouseau revela o verdadeiro culpado
Todos estão reunidos.
JSON está sentado numa cadeira.
COBOL em outra.
Kubernetes parece nervoso.
Terraform evita contato visual.
YAML insiste que sua indentação está perfeitamente correta.
Clouseau começa:
— Mesdames et messieurs... descobri o criminoso.
Silêncio.
Ele aponta dramaticamente.
Para ninguém.
— O culpado é... JSON!
O assistente cochicha:
— Inspetor, JSON não fez nada.
— Exatamente! Isso prova como ele é astuto.
Mas talvez exista uma conclusão melhor.
JSON não revolucionou a computação porque inventou dados estruturados.
Isso já existia muito antes dele.
Também não inventou hierarquias, contratos, mensagens ou serialização.
Sua grande força foi oferecer uma representação extremamente simples e amplamente interoperável para que sistemas heterogêneos pudessem conversar sobre dados.
Um programa COBOL de décadas atrás pode participar de uma arquitetura moderna:
COBOL
│
CICS
│
API
│
JSON
│
Cloud
│
Kubernetes
│
CI/CD
│
Observability
│
IAE isso revela algo que Clouseau quase conseguiu descobrir.
O mainframe não precisa falar a linguagem interna do Kubernetes.
Kubernetes não precisa entender COMP-3.
O aplicativo mobile não precisa conhecer um COPYBOOK.
O sistema consumidor precisa conhecer o contrato na fronteira.
É justamente aí que JSON conquistou seu espaço.
☕ A MORAL DO CASO
Quando alguém disser:
“Mainframe é tecnologia antiga; JSON é tecnologia moderna.”
Clouseau provavelmente derrubará uma estante tentando responder.
Nós podemos fazer melhor.
Um registro COBOL, uma mensagem MQ, um documento XML, um JSON de API e um evento de observabilidade pertencem a gerações e ecossistemas diferentes, mas todos atacam variações de uma questão muito antiga:
Como representar informação de maneira que outro componente consiga compreendê-la corretamente?
A tecnologia muda.
As chaves mudam.
Os protocolos mudam.
Os nomes ficam mais modernos.
Mas o problema fundamental permanece.
E talvez seja por isso que um programador que passou décadas olhando:
01 CUSTOMER.
05 CUSTOMER-ID PIC 9(8).não deveria sentir medo ao encontrar:
{
"customer": {
"id": 12345678
}
}Ele não entrou em outro universo.
Apenas encontrou uma nova maneira de escrever uma velha ideia.
E no corredor da produção, às 03:17, o Inspetor Clouseau ainda procura aquela vírgula desaparecida. ☕🕵️♂️