Boas Práticas de API REST: Como Fazer um Design Consistente
O que são boas práticas de API REST
Boas práticas de API REST são um conjunto de convenções sobre nomenclatura de recursos, uso de verbos HTTP, códigos de status e versionamento que tornam uma API previsível para quem consome. Sem elas, cada endpoint vira uma decisão isolada, e o time que integra a API perde tempo lendo código-fonte para adivinhar o comportamento.
Uma especificação seguida à risca importa menos do que reduzir a superfície de surpresa da API. Quem já usou um endpoint consegue prever como o próximo vai se comportar, sem abrir a documentação toda vez.
Como nomear recursos e usar verbos HTTP corretamente
Um recurso é sempre um substantivo no plural, e o verbo HTTP carrega a ação. /orders
para a coleção, /orders/42 para um item específico. Colocar o verbo na URL, como
/getOrders ou /criarPedido, duplica informação que o método HTTP já contém e obriga
quem lê a decorar uma convenção própria da sua API.
GET /orderslista pedidos.POST /orderscria um pedido novo.GET /orders/42retorna um pedido específico.PATCH /orders/42atualiza parte de um pedido.DELETE /orders/42remove um pedido.
Relacionamentos entram como sub-recurso, /orders/42/items para os itens daquele
pedido. Evite aninhar mais de dois níveis: /users/42/orders/7/items/3 já é difícil de
ler, e geralmente indica que items merece um endpoint próprio, filtrado por
order_id.
Quais códigos de status usar em cada resposta
O código de status é a primeira informação que o cliente da API lê, antes mesmo de abrir
o corpo da resposta. Usar sempre 200 ou sempre 400 genérico obriga quem integra a
inspecionar o corpo inteiro só para saber o que de fato aconteceu.
A faixa 2xx confirma sucesso. 200 serve para leitura e atualização, 201 para
criação, com o header Location apontando para o recurso criado, e 204 para exclusão
sem corpo de resposta. A faixa 4xx sinaliza erro do cliente: 400 para corpo malformado,
401 para autenticação ausente, 403 para autenticação válida sem permissão suficiente,
404 para recurso inexistente, 409 para conflito, como tentar criar um recurso que já
existe. A faixa 5xx fica reservada para erro do servidor.
Um erro de validação de campo pertence à faixa 4xx, nunca à 5xx. Retornar 500 para um
CPF inválido esconde um problema do cliente atrás de um código que deveria sinalizar
falha interna, o que atrapalha tanto o monitoramento quanto quem está integrando a API.
Como paginar, filtrar e ordenar sem sobrecarregar o banco
Toda coleção que pode crescer sem limite precisa de paginação desde o primeiro dia. Esperar o endpoint ficar lento em produção para adicionar paginação obriga a mudar o contrato depois que já existem consumidores presos ao formato antigo.
Paginação por cursor, com um parâmetro no formato ?cursor=abc123&limit=20, escala
melhor que offset em tabelas grandes. Um OFFSET 50000 obriga o banco a percorrer e
descartar cinquenta mil linhas antes de montar a página pedida. Se o volume da tabela é
pequeno, ou a ordenação é estável, offset e limit continuam simples e suficientes.
Filtro e ordenação seguem o mesmo raciocínio de performance do banco por trás do
endpoint. Um filtro como ?status=pago só responde rápido se existir
índice na coluna correspondente. Sem ele, o endpoint
troca a lentidão do lado do cliente por um sequential scan do lado do servidor a cada
chamada.
Como versionar uma API REST sem quebrar quem já usa
Versionar significa dar um caminho estável para quem consome a API continuar
funcionando enquanto você evolui o contrato em paralelo. A forma mais comum, e mais
fácil de comunicar, é o prefixo na URL: /v1/orders, /v2/orders.
Mudança que quebra o contrato, como remover campo, mudar tipo ou renomear atributo, exige versão nova. Mudança aditiva, como um campo opcional a mais ou um endpoint novo, não exige, porque um cliente bem escrito ignora o que não conhece. O erro mais comum é tratar toda mudança como motivo para subir a versão. Isso multiplica versões para manter e reduz a vida útil de cada uma.
Como aplicar essas práticas em uma API que já está em produção
Aplicar tudo de uma vez em uma API que já tem consumidores quebra quem depende do comportamento atual. O caminho seguro é incremental.
- Documente o contrato atual, endpoint por endpoint, antes de mudar qualquer coisa. Sem isso não dá para saber o que realmente está em uso.
- Padronize os códigos de status nos endpoints novos primeiro. Não é preciso corrigir os antigos de imediato.
- Adicione paginação em qualquer coleção que ainda não tem, começando pela que mais cresce.
- Introduza uma versão nova,
/v2, só quando precisar de uma mudança que quebra o contrato, e mantenha a versão anterior no ar por um período de transição comunicado com antecedência. - Monitore o tráfego dos endpoints antigos. Quando cair perto de zero, é seguro descontinuar a versão anterior.
Esse tipo de decisão de arquitetura também tem efeito do lado de dentro da aplicação que consome a API. Se o front-end é React, o gerenciamento de estado escolhido do outro lado da chamada determina se cada resposta nova vira um re-render desnecessário ou não.
O ganho de aplicar boas práticas de API REST aparece na velocidade de quem integra: menos pergunta perdida em chat, menos código defensivo para lidar com inconsistência. O retrabalho cai justamente na hora em que a API mais precisa evoluir. Nenhuma dessas práticas exige reescrever o que já existe: dá para aplicar recurso por recurso, começando pelos endpoints mais usados.
Se sua API cresceu de forma orgânica e hoje é difícil de manter ou de integrar, fale com a gente para revisar a arquitetura junto com o time.