Translate

terça-feira, 19 de junho de 2018

API Status Codes : Quando um Programador Descobre que o Servidor Já Respondeu à Pergunta… Mas Ele Preferiu Consultar Três Logs, Dois Oráculos e um Monge no Deserto

 

Bellacosa Mainframe e o status codes das api numa visão para pequenos gafanhotos

☕ Um Café no Bellacosa Mainframe

API Status Codes sem Mistérios para Programadores COBOL

Quando um Programador Descobre que o Servidor Já Respondeu à Pergunta… Mas Ele Preferiu Consultar Três Logs, Dois Oráculos e um Monge no Deserto

No início da jornada, o jovem programador acreditava que todo erro de API era uma entidade sobrenatural.

Uma criatura invisível.

Um espírito maligno vivendo entre o frontend, o backend, o banco de dados, o firewall, o proxy reverso, o balanceador de carga e aquele serviço terceirizado que ninguém sabia exatamente quem havia contratado.

Quando a aplicação falhava, ele fazia o ritual tradicional:

  1. Reiniciava o navegador.

  2. Limpava o cache.

  3. Reiniciava a aplicação.

  4. Reiniciava o computador.

  5. Culpava a rede.

  6. Culpava o banco de dados.

  7. Culpava o COBOL.

  8. Perguntava à inteligência artificial.

  9. Mandava uma mensagem no grupo da equipe dizendo:
    “Alguém mexeu em produção?”

Então, numa tarde coberta de névoa, enquanto o vento atravessava os corredores do data center e os discos do mainframe giravam como tambores de um templo tecnológico, apareceu o velho mestre.

Ele vestia um quimono gasto, carregava uma caneca de café e segurava nas mãos uma folha contendo quatro símbolos:

2xx
3xx
4xx
5xx

O jovem programador perguntou:

— Mestre, qual é o significado desses números?

O velho respondeu:

— Pequeno gafanhoto, antes de procurar o erro no universo inteiro, leia aquilo que o servidor já lhe disse.

O programador olhou para a tela.

HTTP/1.1 404 Not Found

— Mestre, devo verificar o banco de dados?

— Não.

— O servidor Java?

— Não.

— A aplicação COBOL?

— Não.

— A temperatura da sala do data center?

— Também não.

— Então o que devo verificar?

O mestre tomou um gole de café.

— A URL.

E assim começou a verdadeira arte marcial do debugging de APIs.


O servidor não fala em enigmas

Quando uma API responde, ela não entrega somente dados.

Ela entrega uma estrutura.

Normalmente, uma resposta HTTP possui pelo menos três elementos importantes:

Status
Headers
Body

Por exemplo:

HTTP/1.1 404 Not Found
Content-Type: application/json
X-Correlation-ID: 9812-A7B3

{
  "error": "Cliente não encontrado"
}

O programador iniciante frequentemente olha apenas para o corpo.

O mais apressado olha apenas para a mensagem.

O mais desesperado ignora tudo e abre os logs.

Mas o verdadeiro praticante da arte do debugging observa o conjunto.

O código 404 indica uma classe de problema.

O corpo informa um detalhe.

O cabeçalho X-Correlation-ID pode permitir encontrar a requisição nos logs.

É semelhante a analisar um ABEND em ambiente mainframe.

Receber apenas:

JOB FAILED

não é suficiente.

Você precisa saber:

Qual step?
Qual programa?
Qual return code?
Qual ABEND?
Qual dataset?
Qual mensagem?
Qual horário?
Qual execução?

Em APIs, o status HTTP é como o primeiro código do incidente.

Ele não resolve tudo, mas mostra em qual porta você deve bater.


O caminho completo de uma chamada de API

Muitos desenvolvedores imaginam uma API desta maneira:

Cliente → Servidor

Parece simples.

Quase poético.

Infelizmente, sistemas corporativos raramente possuem a delicadeza de um poema.

O caminho real pode ser:

Aplicação cliente
        ↓
DNS
        ↓
Proxy corporativo
        ↓
Firewall
        ↓
WAF
        ↓
CDN
        ↓
Load balancer
        ↓
API Gateway
        ↓
Servidor web
        ↓
Aplicação
        ↓
Banco de dados
        ↓
Fila
        ↓
Mainframe
        ↓
Outro serviço externo

Quando você recebe um erro, ele pode ter sido produzido por qualquer ponto dessa longa peregrinação.

Um 502, por exemplo, geralmente indica que algum intermediário tentou conversar com outro servidor e recebeu uma resposta inválida.

Um 504 indica que o intermediário esperou, esperou, acendeu uma vela, terminou um café e desistiu.

Um 401 pode ser produzido por um gateway de autenticação antes mesmo de a requisição chegar à aplicação.

Portanto, aprender os códigos HTTP é aprender a localizar o templo onde o problema provavelmente vive.


A primeira família: 1xx — o mensageiro ainda está falando

Os códigos 1xx são pouco vistos no desenvolvimento cotidiano, mas fazem parte do protocolo.

Eles indicam que alguma informação preliminar foi transmitida e que o processo continua.

100 Continue

Imagine que você pretende enviar um arquivo gigantesco para o servidor.

Antes de enviar tudo, o cliente pode perguntar:

Expect: 100-continue

O servidor responde:

HTTP/1.1 100 Continue

Em outras palavras:

“Pode continuar. Ainda não rejeitei sua requisição.”

Isso evita que o cliente envie centenas de megabytes apenas para descobrir depois que não possui autorização.

É como chegar ao portão do mosteiro com vinte caixas e perguntar:

— Posso entrar?

O porteiro responde:

— Continue.

Melhor isso do que carregar tudo até o pátio e descobrir que o templo estava fechado desde 1978.

101 Switching Protocols

Esse código indica mudança de protocolo.

A conexão começou de uma forma e continuará de outra.

É comum em situações de upgrade de comunicação.

103 Early Hints

Permite que o servidor envie pistas antecipadas para o cliente começar a preparar certos recursos antes da resposta final.

É uma espécie de mensagem do mestre:

“Ainda não terminei a explicação, mas já vá abrindo o manual.”


A segunda família: 2xx — a técnica foi executada com sucesso

Os códigos 2xx indicam sucesso sob a ótica do protocolo HTTP.

Mas existe uma diferença importante:

Sucesso HTTP não significa necessariamente sucesso de negócio.

Uma API pode responder 200 OK e, dentro do corpo, informar que uma operação comercial falhou.

Isso é possível, embora frequentemente represente uma API mal projetada.


200 OK

É o sucesso genérico.

Exemplo:

GET /clientes/123

Resposta:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 123,
  "nome": "Vagner",
  "status": "ativo"
}

A requisição foi atendida e o recurso foi retornado.

No mundo COBOL, seria algo semelhante a:

Programa executado
Registro encontrado
Dados retornados
RETURN-CODE = 0

Mas tome cuidado com respostas como:

HTTP/1.1 200 OK

{
  "success": false,
  "message": "Cliente não encontrado"
}

O protocolo diz sucesso.

O corpo diz falha.

É como um job terminar com CC 0000 e imprimir no relatório:

NENHUM REGISTRO FOI PROCESSADO PORQUE O ARQUIVO ESTAVA CORROMPIDO

Tecnicamente terminou.

Funcionalmente, o castelo está em chamas.

A primeira lição é:

Sempre valide o conteúdo da resposta, não apenas o código.


201 Created

O código 201 indica que um novo recurso foi criado.

Requisição:

POST /clientes
Content-Type: application/json

{
  "nome": "Maria",
  "email": "maria@example.com"
}

Resposta:

HTTP/1.1 201 Created
Location: /clientes/845

{
  "id": 845,
  "nome": "Maria",
  "email": "maria@example.com"
}

O cabeçalho Location informa onde o novo recurso pode ser encontrado.

Analogia mainframe:

200 = a consulta funcionou
201 = um novo registro foi gravado

É como executar um WRITE com sucesso em um arquivo VSAM e receber a chave do registro recém-criado.


202 Accepted

Este é um dos códigos mais importantes para quem conhece processamento batch.

O 202 significa:

“Recebi sua solicitação, aceitei o trabalho, mas ele ainda não terminou.”

Exemplo:

POST /relatorios/mensais

Resposta:

HTTP/1.1 202 Accepted
Location: /tarefas/98271

{
  "taskId": 98271,
  "status": "PROCESSING"
}

Isto é praticamente o equivalente web de:

JOB SUBMITTED

Submeter o job não significa que ele terminou.

Ele pode estar:

INPUT
EXECUTION
OUTPUT
HELD
ABENDED

O iniciante vê 202 e comemora.

O mestre pergunta:

— Onde você consulta o resultado?

O 202 normalmente deve ser acompanhado por algum mecanismo de acompanhamento:

GET /tarefas/98271

Resposta posterior:

{
  "taskId": 98271,
  "status": "COMPLETED"
}

Ou, em um dia menos agradável:

{
  "taskId": 98271,
  "status": "FAILED",
  "error": "Database unavailable"
}

204 No Content

O 204 significa sucesso sem corpo de resposta.

Exemplo:

DELETE /clientes/845

Resposta:

HTTP/1.1 204 No Content

A operação funcionou.

Não existe JSON.

Não existe XML.

Não existe mensagem de parabéns.

O servidor apenas cruza os braços e diz:

“Feito.”

Isso provoca um erro clássico em JavaScript:

const data = await response.json();

Se a resposta é 204, não existe JSON.

Então o cliente pode falhar tentando ler algo que nunca foi enviado.

Forma mais segura:

if (response.status === 204) {
  return null;
}

return await response.json();

O programador COBOL compreenderá imediatamente.

É como um programa que termina com RETURN-CODE = 0, mas não gera relatório porque não havia nada a imprimir.


A terceira família: 3xx — o caminho mudou

Os códigos 3xx indicam redirecionamento, reutilização de cache ou mudança de localização.

O servidor não está necessariamente dizendo que existe um erro.

Ele pode estar dizendo:

“Aquilo que você procura está em outro lugar.”


301 Moved Permanently

O recurso mudou definitivamente.

Exemplo:

GET /api/v1/clientes

Resposta:

HTTP/1.1 301 Moved Permanently
Location: /api/v2/clientes

A antiga rota foi substituída.

Isso pode ocorrer por:

  • mudança de domínio;

  • migração para HTTPS;

  • nova versão da API;

  • reestruturação de endpoints;

  • alteração permanente de endereço.

O erro aparece quando o cliente não segue redirecionamentos automaticamente.

O navegador geralmente segue.

Uma aplicação antiga talvez não.

Um programa batch escrito quando televisores ainda possuíam madeira nas laterais pode simplesmente receber o 301 e ficar olhando para ele como um discípulo diante de uma porta fechada.


302 Found

O 302 representa normalmente um redirecionamento temporário.

Um caso comum é autenticação.

Você chama:

GET /api/clientes

O servidor responde:

HTTP/1.1 302 Found
Location: /login

O navegador segue o redirecionamento e recebe:

HTTP/1.1 200 OK
Content-Type: text/html

Então o desenvolvedor reclama:

“A API está retornando HTML em vez de JSON!”

Na realidade, a API redirecionou para a página de login, e o cliente seguiu automaticamente.

A sequência real foi:

GET /api/clientes
        ↓
302 /login
        ↓
200 página HTML

Por isso, ferramentas como curl ajudam muito.

curl -v https://api.exemplo.com/clientes

O modo verboso revela os passos intermediários.


304 Not Modified

O 304 está relacionado a cache.

Ele significa:

“O conteúdo não mudou. Use a cópia que você já possui.”

Primeira requisição:

GET /imagem.png

Resposta:

HTTP/1.1 200 OK
ETag: "abc123"

Requisição posterior:

GET /imagem.png
If-None-Match: "abc123"

Resposta:

HTTP/1.1 304 Not Modified

O servidor não envia novamente o arquivo.

O navegador usa a versão em cache.

Isso economiza:

  • banda;

  • tempo;

  • processamento;

  • custo;

  • tráfego.

Mas também pode criar o famoso bug fantasma:

“Eu alterei o JavaScript, mas o navegador insiste em executar a versão antiga.”

Nesse momento, o culpado pode ser:

Cache-Control
ETag
CDN
Proxy
Service Worker
Cache do navegador

O jovem programador apaga a aplicação inteira.

O mestre apenas pressiona Ctrl + Shift + R.


A quarta família: 4xx — a requisição chegou com problemas

Os códigos 4xx indicam que existe algum impedimento associado à requisição do cliente.

Isso não significa que o frontend é culpado.

Pode haver documentação errada, configurações incorretas, permissões mal atribuídas ou contratos incompatíveis.

O código apenas indica onde começar.


400 Bad Request

O 400 significa requisição inválida.

Possíveis causas:

  • JSON malformado;

  • parâmetro incorreto;

  • data em formato inválido;

  • cabeçalho errado;

  • corpo incompleto;

  • tipo de conteúdo incompatível.

Exemplo:

{
  "nome": "Vagner",
  "idade": 52,
}

A vírgula final pode tornar o JSON inválido.

Outro exemplo:

Content-Type: text/plain

quando a API espera:

Content-Type: application/json

Analogia COBOL:

05 WS-DATA PIC 9(8).

Entrada recebida:

23/07/2026

O humano compreende.

O programa não.

O layout esperava oito dígitos, talvez:

20260723

Quando receber 400, verifique:

Método
URL
Query string
Headers
Content-Type
JSON
Tipos
Datas
Campos obrigatórios
Codificação

401 Unauthorized

O 401 indica problema de autenticação.

Tradução prática:

“Não consegui validar corretamente quem você é.”

Causas comuns:

  • token ausente;

  • token expirado;

  • token inválido;

  • chave de API incorreta;

  • assinatura inválida;

  • usuário inexistente;

  • relógio fora de sincronia.

Exemplo:

Authorization: Bearer token-expirado

Resposta:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

Uma situação curiosa ocorre com tokens JWT.

O token pode possuir:

Data de emissão
Data de expiração
Emissor
Audiência
Escopos
Assinatura

Se o relógio da máquina cliente estiver alguns minutos errado, um token válido pode parecer expirado ou ainda não válido.

Às vezes o grande vilão da autenticação não é um hacker internacional.

É o relógio do servidor.


403 Forbidden

O 403 significa que a identidade pode ser conhecida, mas a operação não é permitida.

Diferença essencial:

401 = não consegui autenticar você
403 = autentiquei você, mas você não possui autorização

Exemplo:

Usuário: Vagner
Perfil: CONSULTA
Operação: DELETE

Resposta:

HTTP/1.1 403 Forbidden

No mundo mainframe, pense em RACF:

Usuário reconhecido
Senha aceita
Acesso ao recurso negado

Você entrou no prédio.

Possui crachá.

Mas a porta da sala de produção continua fechada.

E o segurança não parece disposto a discutir filosofia.


404 Not Found

O 404 significa que a rota ou o recurso não foi encontrado.

Pode ser:

URL errada
Endpoint inexistente
ID inexistente
Versão incorreta
Ambiente errado
Deploy incompleto
Maiúscula ou minúscula diferente
Context path ausente

Exemplo:

GET /clientes/999999

Resposta:

HTTP/1.1 404 Not Found

Existem duas situações diferentes.

A rota não existe

/api/clientez/123

O endpoint foi digitado incorretamente.

O recurso não existe

/api/clientes/999999

O endpoint existe, mas o cliente não.

Outra armadilha:

O endpoint existe em desenvolvimento:

/api/v2/clientes

Mas produção só possui:

/api/v1/clientes

O código está no repositório.

O pipeline ficou verde.

A apresentação para a diretoria foi magnífica.

O endpoint, entretanto, não foi implantado.

O 404 está apenas dizendo:

“Aqui, neste ambiente, nesta rota, isso não existe.”


405 Method Not Allowed

A rota existe, mas o método HTTP não é permitido.

Exemplo:

POST /clientes/123

Resposta:

HTTP/1.1 405 Method Not Allowed
Allow: GET, PUT, DELETE

Diferença:

404 = não encontrei a rota ou o recurso
405 = encontrei a rota, mas esse verbo não é aceito

É como chegar à agência correta, falar com a pessoa correta e pedir a operação errada.


409 Conflict

O 409 indica conflito com o estado atual do recurso.

Exemplos:

  • usuário duplicado;

  • e-mail já cadastrado;

  • versão antiga do registro;

  • assento já reservado;

  • pedido já processado;

  • recurso sendo alterado por outro processo.

Imagine:

Cliente A lê:

{
  "id": 100,
  "saldo": 500,
  "versao": 7
}

Cliente B altera o registro.

Agora a versão é 8.

Cliente A tenta salvar usando a versão 7.

Resposta:

HTTP/1.1 409 Conflict

A requisição é válida.

O problema é que ela nasceu em um passado que já não existe.

É praticamente uma viagem no tempo corporativa.


415 Unsupported Media Type

O formato enviado não é aceito.

Você envia:

Content-Type: application/xml

Mas a API aceita apenas:

Content-Type: application/json

Resposta:

HTTP/1.1 415 Unsupported Media Type

Antes de investigar o banco de dados, examine o cabeçalho.

Muitos incidentes terminam com uma frase humilhante:

“Estávamos enviando XML para um endpoint JSON.”


422 Unprocessable Content

O JSON está bem formado, mas os dados não passam nas regras.

Exemplo:

{
  "nome": "Ana",
  "idade": -17,
  "email": "banana"
}

A sintaxe é válida.

Os valores não são.

Resposta:

HTTP/1.1 422 Unprocessable Content

{
  "errors": [
    {
      "field": "idade",
      "message": "Valor inválido"
    },
    {
      "field": "email",
      "message": "Formato inválido"
    }
  ]
}

Distinção prática:

400 = não consegui interpretar corretamente
422 = interpretei, mas não posso aceitar

Nem todas as APIs seguem essa divisão, mas ela é útil.


429 Too Many Requests

O cliente ultrapassou o limite de requisições.

Resposta:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

Tradução:

“Pare por sessenta segundos.”

O cliente mal projetado interpreta:

“Tente imediatamente mais quinhentas vezes.”

E assim nasce um pequeno ataque de negação de serviço produzido pela própria aplicação.

A solução correta inclui:

  • respeitar Retry-After;

  • usar backoff exponencial;

  • adicionar jitter;

  • reduzir concorrência;

  • usar cache;

  • evitar polling excessivo.

Exemplo:

1ª falha → espera 1 segundo
2ª falha → espera 2 segundos
3ª falha → espera 4 segundos
4ª falha → espera 8 segundos

Com jitter, adiciona-se um pequeno intervalo aleatório.

Isso evita que milhares de clientes voltem exatamente ao mesmo tempo, como discípulos famintos quando alguém anuncia que o café está pronto.


A quinta família: 5xx — o servidor tropeçou

Os códigos 5xx indicam falha do lado servidor ou de alguma infraestrutura associada.

Mas cuidado:

Uma requisição específica pode acionar um bug do servidor.

O cliente pode ser o gatilho, embora a responsabilidade técnica continue sendo da aplicação.


500 Internal Server Error

É o erro genérico.

Pode representar:

  • exceção não tratada;

  • variável nula;

  • banco indisponível;

  • configuração incorreta;

  • falha de serialização;

  • falta de memória;

  • arquivo ausente;

  • erro de programação;

  • dependência indisponível.

Resposta ruim:

HTTP/1.1 500 Internal Server Error

Something went wrong

Resposta melhor:

HTTP/1.1 500 Internal Server Error
X-Correlation-ID: A7C9-2218

{
  "status": 500,
  "message": "Não foi possível concluir a operação",
  "correlationId": "A7C9-2218"
}

O correlation ID é extremamente importante.

Ele permite localizar a mesma transação nos logs de:

Gateway
Aplicação
Banco
Fila
Mainframe
Serviço externo

O usuário não deve receber stack trace, senha, SQL completo ou detalhes internos.

Isso seria como imprimir o conteúdo do dump de produção na porta da empresa.


502 Bad Gateway

Um gateway ou proxy recebeu uma resposta inválida do servidor posterior.

Fluxo:

Cliente
   ↓
Gateway
   ↓
Backend

O gateway está ativo.

O backend falhou, respondeu de forma inválida ou não aceitou a conexão.

Causas:

  • serviço caiu;

  • DNS interno falhou;

  • porta errada;

  • certificado inválido;

  • container reiniciando;

  • conexão recusada;

  • resposta malformada.

Tradução kung fu:

O mensageiro chegou ao portão, mas o mestre do templo não respondeu corretamente.


503 Service Unavailable

O serviço está temporariamente indisponível.

Possíveis causas:

  • manutenção;

  • sobrecarga;

  • nenhuma instância saudável;

  • aplicação iniciando;

  • pool de conexões esgotado;

  • circuit breaker aberto;

  • banco fora do ar.

Resposta:

HTTP/1.1 503 Service Unavailable
Retry-After: 120

Diferença:

500 = ocorreu uma falha interna inesperada
503 = o serviço não consegue atender agora

Em ambiente com containers, um 503 pode significar:

Load balancer funcionando
Nenhum pod saudável disponível

O restaurante está aberto.

A cozinha desapareceu.


504 Gateway Timeout

O gateway esperou pelo backend, mas o tempo limite expirou.

Fluxo:

Cliente
   ↓
Gateway
   ↓
API
   ↓
Banco
   ↓
Mainframe

O gateway espera 30 segundos.

O backend demora 45.

Resultado:

HTTP/1.1 504 Gateway Timeout

O detalhe mais valioso pode ser o tempo.

Se o erro ocorre sempre em exatamente 30 segundos, existe grande chance de um timeout configurado nessa camada.

Por exemplo:

Gateway timeout: 30 s
API timeout: 60 s
Banco responde em 42 s

A aplicação ainda trabalha quando o gateway abandona a conversa.

A solução não é automaticamente aumentar o timeout.

Talvez seja melhor:

  • otimizar SQL;

  • criar processamento assíncrono;

  • devolver 202;

  • usar fila;

  • paginar;

  • criar cache;

  • dividir o trabalho.

Aumentar o timeout sem investigar é como ensinar o discípulo a esperar mais tempo diante de uma porta emperrada.


O perigo dos retries

Nem toda chamada deve ser repetida.

Métodos normalmente idempotentes

GET
PUT
DELETE

Em princípio, repetir deve conduzir ao mesmo estado final.

POST normalmente não é idempotente

Exemplo:

POST /pagamentos

O servidor processa o pagamento.

A resposta demora.

O gateway devolve 504.

O cliente repete.

Resultado possível:

Pagamento 1 criado
Pagamento 2 criado
Cliente furioso
Reunião extraordinária
PowerPoint com 74 slides

Para evitar duplicidade, APIs podem aceitar:

Idempotency-Key: pedido-82719-pagamento-1

Se a mesma operação for repetida, o servidor reconhece a chave.

Retries fazem mais sentido em códigos como:

408
429
502
503
504

Mesmo assim, devem possuir:

  • limite de tentativas;

  • backoff;

  • jitter;

  • controle de duplicidade;

  • respeito ao Retry-After.

Não repita cegamente:

400
401
403
404
409
422

Uma requisição errada repetida cem vezes continua errada.

Ela apenas fica mais barulhenta.


Passo a passo para investigar uma API

Quando surgir um erro, siga esta ordem.

Passo 1 — veja o método

GET
POST
PUT
PATCH
DELETE

A rota pode aceitar apenas alguns métodos.

Passo 2 — confira a URL completa

Verifique:

Protocolo
Domínio
Porta
Context path
Versão
Endpoint
Query string
Barra final
Maiúsculas e minúsculas

Passo 3 — leia o status

Classifique:

1xx → continuação
2xx → sucesso
3xx → redirecionamento ou cache
4xx → problema associado à requisição
5xx → problema no servidor ou infraestrutura

Passo 4 — leia os headers

Especialmente:

Authorization
Content-Type
Accept
Location
Retry-After
ETag
X-Correlation-ID

Passo 5 — leia o corpo

A mensagem pode indicar:

Campo inválido
Token expirado
Recurso ausente
Versão conflitante
Limite excedido

Passo 6 — observe o tempo

Erro em 10 ms → falha imediata
Erro em 30 s exatos → timeout provável
Erro variável → dependência instável

Passo 7 — procure o correlation ID

Use-o nos logs.

Passo 8 — reproduza com ferramenta simples

Exemplo:

curl -v \
  -H "Authorization: Bearer TOKEN" \
  -H "Accept: application/json" \
  https://api.exemplo.com/clientes/123

O curl -v mostra:

  • conexão;

  • certificados;

  • headers enviados;

  • headers recebidos;

  • redirecionamentos;

  • status;

  • detalhes úteis.

Passo 9 — só então abra os logs

Os logs não devem ser o primeiro lugar.

Devem ser o lugar correto após o status indicar a direção.


O algoritmo COBOL do guerreiro HTTP

Um programador COBOL pode pensar desta forma:

EVALUATE TRUE

   WHEN HTTP-STATUS >= 100
    AND HTTP-STATUS < 200
      DISPLAY 'RESPOSTA INFORMATIVA'

   WHEN HTTP-STATUS >= 200
    AND HTTP-STATUS < 300
      DISPLAY 'SUCESSO HTTP'
      PERFORM VALIDAR-RESULTADO-FUNCIONAL

   WHEN HTTP-STATUS >= 300
    AND HTTP-STATUS < 400
      DISPLAY 'VERIFICAR REDIRECT OU CACHE'
      PERFORM ANALISAR-LOCATION

   WHEN HTTP-STATUS >= 400
    AND HTTP-STATUS < 500
      DISPLAY 'VERIFICAR REQUEST'
      PERFORM ANALISAR-AUTH
      PERFORM ANALISAR-HEADERS
      PERFORM ANALISAR-BODY

   WHEN HTTP-STATUS >= 500
    AND HTTP-STATUS < 600
      DISPLAY 'VERIFICAR SERVIDOR'
      PERFORM LOCALIZAR-CORRELATION-ID
      PERFORM CONSULTAR-LOGS

   WHEN OTHER
      DISPLAY 'STATUS INESPERADO'

END-EVALUATE.

Mas o mestre acrescentaria:

IF HTTP-STATUS = 200
   AND BUSINESS-RESULT NOT = 'SUCCESS'
      DISPLAY 'HTTP OK, NEGOCIO NAO OK'
END-IF.

Porque o sábio sabe que nem todo 200 representa felicidade.


Curiosidades do templo HTTP

Curiosidade 1 — 401 possui um nome confuso

401 Unauthorized é usado principalmente para falha de autenticação.

O código mais associado à falta de autorização é 403.

O nome histórico permaneceu, e agora gera confusão em várias gerações de desenvolvedores.

Curiosidade 2 — 404 pode proteger informações

Alguns sistemas devolvem 404 em vez de 403 para não revelar que determinado recurso existe.

Em vez de dizer:

“Existe, mas você não pode acessar.”

o sistema responde:

“Nunca ouvi falar.”

É o equivalente digital do monge que esconde o pergaminho atrás das costas.

Curiosidade 3 — 418 existe como brincadeira

O código 418 I’m a Teapot nasceu como uma piada relacionada a um protocolo fictício de controle de bules de café.

Não deve ser usado como erro sério de produção.

Embora, em certas empresas, talvez descreva com precisão a maturidade da arquitetura.

Curiosidade 4 — 200 pode esconder desastre

Algumas APIs antigas retornam 200 para tudo.

Exemplo:

{
  "status": "ERROR",
  "message": "Database unavailable"
}

Isso dificulta:

  • monitoramento;

  • alertas;

  • métricas;

  • retries;

  • tratamento automático.

O protocolo foi criado para comunicar semântica.

Ignorá-lo é como comprar um painel de instrumentos e cobrir todos os indicadores com fita adesiva.

Curiosidade 5 — o tempo é um código invisível

Um 500 em 5 milissegundos e um 500 em 60 segundos provavelmente possuem causas diferentes.

O tempo de resposta é quase um segundo status.


Easter egg: o mestre e o código 404

Conta-se que um jovem discípulo passou três dias procurando um endpoint.

Ele verificou:

  • banco de dados;

  • certificados;

  • filas;

  • firewall;

  • mainframe;

  • memória;

  • CPU;

  • logs;

  • DNS;

  • fases da lua.

Ao final, o mestre perguntou:

— Qual URL você chamou?

O discípulo respondeu:

/api/v1/cilentes

O mestre permaneceu em silêncio.

O discípulo percebeu a troca de letras.

Perguntou:

— Por que não me avisou antes?

O mestre respondeu:

— Eu avisei.

— Quando?

— No primeiro 404.

Naquela noite, o discípulo aprendeu duas lições:

  1. O servidor fala.

  2. O ego do desenvolvedor nem sempre escuta.


A regra final do Bellacosa Mainframe

Guarde este mapa:

1xx → continue observando
2xx → confirme o resultado
3xx → siga o caminho
4xx → revise a requisição
5xx → investigue o servidor

Depois aprofunde:

Status
+ método
+ URL
+ headers
+ body
+ duração
+ correlation ID
= diagnóstico

O código HTTP não é a solução completa.

Ele é a primeira pista.

Ele não diz necessariamente qual linha falhou, qual tabela travou ou qual container decidiu abandonar esta dimensão.

Mas reduz o universo de possibilidades.

Em vez de perguntar:

“O que pode estar errado em toda a arquitetura?”

você pergunta:

“Por que este cliente recebeu um 401?”

ou:

“Qual upstream provocou este 502?”

ou:

“Por que a chamada sempre termina em 504 após 30 segundos?”

A pergunta fica menor.

A investigação fica objetiva.

O incidente deixa de ser uma lenda oriental contada por desenvolvedores apavorados ao redor de um monitor.

E torna-se engenharia.

No último episódio, o jovem programador recebeu uma nova mensagem:

HTTP/1.1 403 Forbidden

A equipe começou a correr.

Um administrador abriu os logs.

Outro reiniciou o servidor.

Alguém sugeriu aumentar a memória.

Um consultor propôs migrar tudo para Kubernetes.

O jovem permaneceu sentado.

Tomou um gole de café.

Abriu o token.

Verificou os escopos.

Descobriu que o usuário possuía permissão de leitura, mas não de exclusão.

Corrigiu a autorização.

A chamada retornou:

HTTP/1.1 204 No Content

O velho mestre observou de longe e perguntou:

— O que a API disse?

O programador respondeu:

— Nada.

O mestre sorriu.

— Então finalmente funcionou.

Sem comentários:

Enviar um comentário

Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988