Pular para o conteúdo principal

Conceitointermediário

REST

Visão Geral

REST é um estilo arquitetural baseado em recursos identificados por URL, manipulados por um conjunto fixo de verbos, com semântica definida pelo próprio HTTP.

Quase nenhuma API chamada de REST é REST no sentido original — a maioria é "HTTP com JSON", o que é legítimo e não é a mesma coisa.

A distinção importa menos como pureza e mais pelo que se perde ao ignorá-la: cache, idempotência, tratamento uniforme de erro e evolução — tudo isso o protocolo já oferece, de graça, para quem usa sua semântica.

Problema

O padrão mais comum em APIs HTTP é tunelar chamadas de método:

POST /criarPedido
POST /buscarPedidoPorId
POST /cancelarPedido

Isso funciona, e joga fora o que o protocolo dá. Tudo é POST, então nada é cacheável nem seguro de repetir. Erros viram 200 com um campo sucesso: false, então nenhum intermediário — proxy, gateway, cliente — entende o que aconteceu.

O resultado é uma API que precisa reimplementar, em convenção própria, coisas que o HTTP já resolve.

Conceitos Centrais

Recurso, não operação

A modelagem central: a URL identifica coisas, e o verbo diz o que se faz com elas.

GET /pedidos/123 obter
PUT /pedidos/123 substituir
PATCH /pedidos/123 alterar parcialmente
DELETE /pedidos/123 remover
POST /pedidos criar

A pergunta que orienta: se isto fosse um documento, qual seria seu endereço?

Ações que não cabem em substantivo — cancelar, aprovar, reprocessar — costumam revelar um recurso escondido. "Cancelar pedido" pode ser POST /pedidos/123/cancelamento: o cancelamento é uma coisa, com data, motivo e autor.

Isso não é jogo de palavras. O cancelamento como recurso tem identidade, pode ser consultado e auditado — o que a operação POST /cancelarPedido não tem.

Segurança e idempotência vêm do verbo

A propriedade mais útil e a mais ignorada:

GET, HEAD seguro e idempotente — não altera; pode repetir, cachear, pré-buscar
PUT, DELETE idempotente — repetir tem o mesmo efeito
POST nenhum dos dois — repetir cria de novo
PATCH nenhum dos dois — depende do que se envia

Isso não é convenção decorativa: proxies, navegadores, clientes e malhas de serviço agem sobre essas garantias. Um GET que altera estado será repetido por uma pré-busca. Um POST sem chave de idempotência será duplicado por uma retentativa.

Ver idempotência.

Código de status é parte do contrato

200/201/204 sucesso, com ou sem corpo
400 a requisição está errada — não adianta repetir
401/403 não autenticado / não autorizado
404 não existe
409 conflito de estado
422 sintaxe válida, semântica inválida
429 excesso de requisições — repita depois
5xx erro do servidor — repetir pode funcionar

A divisão entre 4xx e 5xx é o que permite ao cliente decidir se repete. Uma API que devolve 200 com erro no corpo tira essa decisão de quem chama, e obriga cada cliente a reimplementar a classificação.

O que quase ninguém faz: hipermídia

No REST original, a resposta traz os links das próximas ações possíveis, e o cliente navega por eles em vez de construir URLs.

A promessa é desacoplar o cliente da estrutura de endereços e comunicar transições de estado — um pedido pago traz o link de estorno; um pendente, não.

A adoção é baixíssima, e vale ser honesto sobre por quê: a maioria dos clientes é escrita contra uma especificação e não ganha nada em descobrir links em tempo de execução. O custo aparece imediatamente, o benefício raramente.

Onde ela paga: APIs públicas de vida longa, com muitos clientes que o provedor não controla.

Versão: prefira não

Ver evolução de esquema. Adicionar campo é livre; adicionar recurso é livre. A maior parte da evolução de uma API HTTP cabe em mudança compatível.

Versionar na URL é a forma mais comum e a mais visível — e cada versão viva é código a manter.

Paginação, filtro e ordenação são contrato

Coleções grandes precisam de paginação, e a escolha tem consequência:

Por deslocamento — simples, e a página muda se registros são inseridos durante a navegação.

Por cursor — estável sob inserção, e não permite pular para uma página arbitrária.

Qualquer que seja, ela precisa estar no contrato — inclusive o limite máximo e o que acontece ao pedir mais.

Modelo Mental

REST é usar a semântica do HTTP, não passar por cima dela. Cada garantia ignorada é uma que você vai reimplementar pior.

Quando Usar

  • O cliente precisa da resposta para continuar.
  • O modelo é naturalmente de recursos com ciclo de vida.
  • Consumidores diversos, incluindo navegadores.
  • Cache de HTTP tem valor.
  • API pública, onde ferramental universal importa.
  • Simplicidade operacional pesa mais que eficiência de transporte.

Quando Não Usar

Quando a consequência é assíncrona. Ver integração por mensageria.

Quando o cliente precisa de campos muito variáveis. Ver GraphQL.

Comunicação interna de altíssima frequência. Ver gRPC — o custo de serialização e de conexão pesa.

Fluxos bidirecionais ou de longa duração.

Transferência de grandes volumes em lote. Ver integração em lote.

Quando a operação não é sobre um recurso. Forçar substantivo em cálculos e buscas complexas produz modelagem torturada — ali um endpoint de operação é mais honesto.

Alternativas

  • GraphQL — quando o consumo é variável.
  • gRPC — interno, alta frequência, contrato forte.
  • Mensageria — assíncrono.
  • Webhooks — para notificar em vez de ser consultado.

Trade-offs

RESTgRPC
Ferramental universalPrecisa de suporte
Legível por humanosBinário
Cache de HTTPNão nativo
Contrato frequentemente frouxoForte por definição
Mais bytesCompacto
RESTGraphQL
Resposta fixa por recursoCliente escolhe
Cache simplesDifícil
Várias chamadas para comporUma
Custo previsívelConsulta pode ser cara

Modos de Falha

Tudo via POST. Nada é cacheável nem seguro de repetir.

200 com erro no corpo. O cliente não sabe se repete.

GET com efeito colateral. Pré-busca dispara a ação.

Sem chave de idempotência em criação. Retentativa duplica.

Coleção sem paginação. Uma consulta devolve tudo e derruba os dois lados.

Sequência de chamadas em laço. O cliente faz N requisições para montar uma tela — o problema que motiva GraphQL.

Erros Comuns

Modelar operações em vez de recursos.

Não usar os códigos de status.

Não oferecer chave de idempotência em POST.

Versionar por reflexo.

Paginação fora do contrato.

Expor o modelo interno do banco como recurso. O recurso é parte do contrato público; o modelo interno precisa poder mudar.

Exemplo Real

Uma operadora de logística expunha uma API HTTP com 40 endpoints, todos POST, todos devolvendo 200 com {sucesso: bool, erro: string}.

Quatro consequências, todas descobertas separadamente:

Retentativas duplicando remessas. O cliente móvel repetia em falha de rede. Como tudo era POST sem chave de idempotência, cada repetição criava uma remessa nova. Cerca de 300 remessas duplicadas por mês, tratadas manualmente pelo suporte.

Nenhum cache. A consulta de status de remessa era o endpoint mais chamado — 40% do tráfego — e não podia ser cacheada por ser POST. O banco absorvia tudo.

Classificação de erro na aplicação. Cada um dos onze clientes tinha sua própria lógica para decidir se o texto do campo erro era retentável. Três estavam errados, e repetiam indefinidamente em erros permanentes.

Gateway inútil. O gateway não conseguia aplicar limite de taxa por tipo de operação, nem cachear, nem reportar taxa de erro — porque tudo era POST com 200.

A migração foi feita em paralelo, com a API antiga mantida por catorze meses.

Consultas viraram GET com cache de 30 segundos. O tráfego ao banco caiu 60%.

Códigos de status reais. Os clientes deletaram a classificação própria e passaram a usar 4xx contra 5xx.

Chave de idempotência obrigatória em criação. As duplicatas foram a zero.

Recursos em vez de operações. POST /remessas/{id}/cancelamento substituiu POST /cancelarRemessa. O cancelamento passou a ser consultável, o que resolveu uma demanda antiga de auditoria que ninguém tinha ligado a isso.

O que se registrou depois: nenhuma das quatro correções era sobre pureza de estilo. Cada uma removeu código que existia só para compensar uma garantia do protocolo que estava sendo desperdiçada.

Conceitos Relacionados

Exercício Prático

Pegue a API do seu time e conte quantos endpoints são POST. Para cada um, pergunte: isto altera estado?

Os que não alteram deveriam ser GET — e cada um é cache e retentativa segura que você está deixando na mesa.

Perguntas de Entrevista

  • Por que a distinção entre 4xx e 5xx importa para o cliente?
  • O que se perde ao fazer tudo por POST?
  • Como modelar "cancelar pedido" como recurso, e o que se ganha com isso?

Para Aprofundar

  • Fielding, Roy. Architectural Styles and the Design of Network-based Software Architectures. Tese de doutorado, 2000.
  • Richardson, Leonard; Amundsen, Mike. RESTful Web APIs. O'Reilly, 2013.
  • Allamaraju, Subbu. RESTful Web Services Cookbook. O'Reilly, 2010.
Terminou de ler este documento?Seu progresso fica salvo apenas neste navegador.