DevGuideTK
← Trilha Backend

Design de APIs REST

Recursos, nomes, códigos de status e formato de erros em uma API previsível.

As decisões de desenho de uma API REST se repetem em todo projeto. Esta página compara as mais comuns. A regra que vale para todas: decida uma vez, registre num guia de estilo e aplique em toda a API.

PUT ou PATCH

PUTPATCH
SignificadoSubstitui o recurso inteiro pelo enviadoAltera só os campos enviados
Campo omitidoFica vazio ou recebe o valor padrãoContinua como estava
IdempotenteSimDepende do formato
FormatoO recurso completoJSON Merge Patch (application/merge-patch+json) ou JSON Patch

Na prática, a maioria das APIs usa PATCH com JSON Merge Patch: o cliente envia só os campos que mudam, e null remove um campo.

PATCH /clientes/42
Content-Type: application/merge-patch+json

{ "telefone": "+55 41 99999-0000", "apelido": null }

O risco do PUT mal implementado: um cliente antigo, que não conhece um campo novo, envia o recurso sem ele e apaga o valor sem perceber.

Identificadores

TipoExemploVantagensCuidados
Sequencial981Curto, legível, ordenadoRevela volume de negócio e facilita enumerar recursos
UUID v47e2398da-c68a-...Impossível de adivinharLongo; sem ordem, prejudica índices do banco
UUID v7 ou ULID0193f6a2-...Impossível de adivinhar e ordenado por tempoRevela o momento de criação
Prefixadoped_2Nf8...O tipo do recurso fica visível no próprio identificadorConvenção a manter

Identificadores sequenciais expostos permitem que alguém percorra /pedidos/1, /pedidos/2 e assim por diante. Isso só é um problema de segurança se a autorização falhar, mas revela informação de negócio de qualquer forma: quantos pedidos a empresa recebeu ontem. Muitos sistemas usam o sequencial internamente e um identificador público diferente na API.

Listas: o que toda lista precisa

NecessidadeConvenção comum
PaginaçãoPor cursor: ?limite=20&cursor=..., com o próximo cursor na resposta
FiltrosParâmetros com o nome do campo: ?status=pago&clienteId=42
Ordenação?ordem=-criadoEm (o sinal indica ordem decrescente)
Campos?campos=id,status para respostas menores (opcional)

Toda lista precisa de paginação desde o primeiro dia. Uma lista que devolve tudo funciona com 50 registros e derruba o serviço com 500 mil. O tópico de paginação aprofunda as opções.

Formato da resposta: envelope ou não

Recurso diretoEnvelope
Exemplo{ "id": "981", "status": "pago" }{ "data": { "id": "981" }, "meta": { ... } }
VantagemSimples, segue o HTTPLugar fixo para paginação e metadados
Errosproblem+json, com o status HTTPÀs vezes "success": false, o que repete o status

Uma combinação equilibrada: recursos individuais sem envelope; listas com um objeto que contém os itens e as informações de paginação; erros sempre em problem+json, com o código de status correto.

{
  "itens": [{ "id": "981", "status": "pago" }],
  "proximoCursor": "eyJpZCI6OTgxfQ"
}

Operações demoradas

Gerar um relatório, processar um arquivo grande ou importar mil registros pode levar minutos. Manter o pedido HTTP aberto esse tempo todo é frágil: proxies e balanceadores derrubam conexões longas.

POST /relatorios
→ 202 Accepted
  Location: /relatorios/77

GET /relatorios/77
→ 200 { "status": "processando" }
→ 200 { "status": "concluido", "arquivo": "/relatorios/77/arquivo" }

O pedido inicial devolve 202 Accepted com o endereço de um recurso que representa a operação. O cliente consulta esse endereço, ou recebe um webhook quando terminar.

Desenho primeiro ou código primeiro

AbordagemComo funcionaQuando usar
Contrato primeiroEscreve o OpenAPI, revisa com quem vai consumir, gera código e testes a partir deleAPIs públicas, vários times consumindo, contratos difíceis de mudar
Código primeiroEscreve o código, e o framework gera o OpenAPIAPIs internas, um único cliente, iteração rápida

Nos dois casos, o documento OpenAPI deve existir e estar atualizado. O tópico de documentação mostra como.

Resumo da decisão

  1. Endereços com substantivos no plural; ações especiais como sub-recursos.
  2. Status previsível por operação; 201 com Location ao criar.
  3. Erros sempre em application/problem+json, com type estável.
  4. Alterações parciais com PATCH e JSON Merge Patch.
  5. Identificadores públicos que não revelam volume nem podem ser percorridos.
  6. Listas sempre paginadas; operações demoradas com 202.
  7. Um guia de estilo curto, aplicado a todas as rotas.

O próximo nível mostra a criação de um recurso com validação e erros no formato padrão nas cinco linguagens, com o resultado de cada uma.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Escrever o guia de estilo da nossa API

    Quero escrever um guia de estilo curto para as APIs da minha equipe, para que todas as rotas sigam as mesmas regras.
    
    Pergunte qual linguagem e framework usamos, se as APIs são públicas ou internas e quantas equipes as consomem.
    
    Me ajude a decidir e registrar, uma decisão por vez, explicando as opções:
    1. Convenção de endereços e nomes.
    2. PUT ou PATCH, e qual formato de PATCH.
    3. Formato dos erros.
    4. Nomes de campos, datas, dinheiro e identificadores.
    5. Formato das listas e paginação.
    6. Operações demoradas.
    7. Contrato primeiro ou código primeiro.
    
    Termine com o guia em uma página, pronto para o repositório.
  • Identificadores públicos

    Quero escolher o tipo de identificador que a minha API vai expor.
    
    Compare identificadores sequenciais, UUID v4, UUID v7, ULID e identificadores prefixados: tamanho, ordenação, impacto nos índices do banco, o que cada um revela e o risco de enumeração.
    
    Explique também a estratégia de ter um identificador interno e outro público, e como migrar uma API que já expõe identificadores sequenciais.
    
    Pergunte qual banco eu uso e o volume esperado, e recomende uma opção.
  • Revisar o desenho de uma API existente

    Vou colar abaixo a lista de rotas da minha API, ou o documento OpenAPI, com exemplos de respostas de sucesso e de erro. Revise o desenho.
    
    Verifique, e para cada item aponte os problemas com exemplos:
    1. Os endereços usam substantivos, plural e um padrão consistente?
    2. Há ações em GET ou verbos nos endereços?
    3. Os códigos de status são adequados a cada operação?
    4. Os erros seguem um formato único?
    5. As respostas expõem campos internos?
    6. As listas são paginadas?
    7. Os nomes de campos, datas e valores monetários seguem um padrão?
    
    Para cada problema, mostre a correção e diga se ela quebraria clientes existentes, e como migrar se quebrar.
    
    Rotas e exemplos:
    [cole aqui]