DevGuideTK
← Trilha Backend

Documentação e OpenAPI

O contrato da API como arquivo versionado, de onde saem documentação, clientes e testes.

As decisões sobre o contrato da API são quatro: de onde o arquivo nasce, como garantir que ele diz a verdade, como evitar mudanças que quebram quem integra e o que publicar a partir dele.

De onde o arquivo nasce

Gerado pelo códigoEscrito antes do códigoGerado de esquemas compartilhados
Fonte da verdadeRotas e tiposO arquivo OpenAPIEsquemas (Zod, Pydantic, structs) usados para validar e documentar
Esforço inicialMínimoEscrever e revisar o arquivoMédio
Revisão do contratoDepois do código prontoAntes do código, por quem vai integrarJunto com o código
Risco típicoDocumentar o que não é aplicadoO código se afasta do arquivoRecursos do framework fora do esquema
Bom paraAPIs internas, um time sóAPIs públicas e parceiros, vários timesA maioria dos projetos novos

A terceira coluna é a que mais reduz divergências: o mesmo esquema que valida a entrada gera a documentação. No teste do nível Conceito, Fastify, FastAPI e huma funcionam assim, e as divergências encontradas neles foram de detalhe. No ASP.NET Core 9, as anotações iam para a documentação, mas não validavam nada, e a especificação prometia regras que não existiam.

Escrever o arquivo antes compensa quando o contrato precisa ser discutido com quem vai usar a API antes de existir código: parceiros, outro time, o aplicativo de celular. Os dois lados combinam o arquivo, o front-end começa com um servidor de mentira, e o back-end implementa o combinado.

Como garantir que o arquivo diz a verdade

TécnicaO que confereQuando roda
Verificador de estilo (Redocly CLI, Spectral)A forma do arquivo: campos obrigatórios da especificação, nomes, convenções do timeA cada mudança no arquivo
Teste de contrato (Schemathesis)Se a API responde o que o arquivo promete, com pedidos gerados a partir deleNa integração contínua, contra a API em execução
Validação em tempo de execuçãoRecusa pedidos, e opcionalmente respostas, que não batem com o arquivoEm cada pedido
Tipos gerados no clienteSe o código do cliente usa os campos e tipos certosNa compilação do cliente

Nenhuma técnica sozinha basta. O verificador de estilo não sabe o que a API faz. O teste de contrato não sabe se o arquivo está bem escrito. As duas juntas, na integração contínua, pegam a maior parte dos problemas do nível Conceito.

O teste de contrato tem um efeito colateral útil: ele confere os dois lados. No teste, o FastAPI recusou um total "0.00" que o contrato permitia, e a correção era no contrato, que tinha esquecido a regra.

Regras do time no verificador

Os verificadores aceitam regras próprias. As que mais valem a pena, porque pegam os erros do nível Conceito:

RegraPor quê
Todo esquema de objeto declara requiredClientes gerados sem campos obrigatórios tratam tudo como opcional
Valores monetários não usam numbernumber vira ponto flutuante na maioria das linguagens
Toda operação documenta pelo menos um 4xxErros fazem parte do contrato
Respostas de erro usam application/problem+jsonUm formato de erro único para todas as rotas
Campos em snake_case (ou camelCase), sem misturarConsistência para quem integra

Como evitar mudanças que quebram

MudançaCompatível?
Nova rota, novo campo opcional na entrada, novo campo na respostaSim
Novo campo obrigatório na entradaNão
Remover ou renomear um campo da respostaNão
Mudar o tipo de um campoNão
Novo valor num enum da respostaNão, para clientes que tratam todos os valores
Restringir a validação (máximo menor, padrão mais rígido)Não

Com o arquivo versionado no repositório, uma etapa da integração contínua compara o contrato da mudança com o da versão publicada e falha quando há uma mudança incompatível. No teste, o oasdiff classificou corretamente as quatro mudanças do nível Conceito. Quando a mudança é necessária, ela passa a ser uma decisão explícita: uma nova versão da API, como descreve o tópico de versionamento.

Para os enum que vão crescer, avise desde o começo. O oasdiff sugere a extensão x-extensible-enum, e a documentação deve dizer que valores novos podem aparecer e que o cliente deve tratar valores desconhecidos.

O que publicar a partir do arquivo

SaídaPara quemCuidados
Documentação navegável (Swagger UI, Redoc, Scalar)Quem integraExemplos reais em cada operação; descrição dos erros
Tipos e clientes geradosQuem consome, inclusive o próprio front-endGerar na integração contínua, não à mão; fixar a versão do gerador
Servidor de mentira (Prism)Front-end e parceiros, antes da API existirUsar os exemplos do arquivo
Coleção de pedidos (Postman, Bruno, Insomnia)Testes manuaisImportar do arquivo, em vez de manter à parte

Gerar só os tipos costuma valer mais que gerar o cliente inteiro. Com o openapi-typescript, o compilador recusou no teste um total numérico e um campo com o nome errado, sem nenhum código gerado em execução. Clientes completos, do openapi-generator, ajudam em linguagens sem uma boa biblioteca HTTP, mas produzem muito código para revisar e atualizar.

Resumo da decisão

  1. Esquemas compartilhados para validar e documentar com a mesma fonte, ou o arquivo antes do código quando o contrato precisa ser combinado com outros times.
  2. Verificador de estilo com as regras do time, a cada mudança no arquivo.
  3. Teste de contrato na integração contínua, contra a API em execução.
  4. Comparação de versões do contrato, falhando em mudanças incompatíveis.
  5. Tipos gerados para os clientes, inclusive o próprio front-end.
  6. Erros documentados, com um formato único.

O próximo nível mostra as cinco APIs de exemplo, o contrato escrito à mão e os comandos de verificação, teste de contrato e comparação de versões.

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.

  • Escolher como manter o contrato

    Quero definir como o contrato OpenAPI da minha API vai ser produzido e mantido.
    
    Pergunte qual linguagem e framework eu uso, quem consome a API (front-end próprio, outros times, parceiros, público) e se já existe algum arquivo OpenAPI.
    
    Recomende para o meu caso, explicando o porquê:
    1. Gerar pelo código, escrever antes ou usar esquemas compartilhados.
    2. Como garantir que o arquivo e o código concordam.
    3. Quais verificações rodar na integração contínua.
    4. O que publicar a partir do arquivo: documentação, tipos, servidor de mentira.
  • Regras de estilo para o contrato

    Quero criar regras de estilo para os contratos OpenAPI do meu time, para rodar num verificador como o Redocly CLI ou o Spectral.
    
    Pergunte quais convenções o time já segue (nomes de campos, formato de erros, paginação, datas, dinheiro).
    
    Depois proponha um conjunto de regras, explicando o problema que cada uma evita, e escreva a configuração para o verificador que eu escolher. Inclua pelo menos: required em todos os objetos, dinheiro fora de number, erros documentados em todas as operações e um formato único de erro.
  • Gerar clientes a partir do contrato

    Quero gerar clientes ou tipos a partir do contrato OpenAPI da minha API.
    
    Pergunte em quais linguagens estão os consumidores e como eles chamam a API hoje.
    
    Compare para o meu caso:
    1. Gerar só os tipos ou gerar o cliente completo.
    2. As ferramentas de cada linguagem.
    3. Onde gerar: na integração contínua, num pacote publicado, ou no próprio projeto consumidor.
    4. Como lidar com valores novos em enum e campos novos sem quebrar os clientes.