40 Regras de Design de API (FastAPI/Django/Flask)
Quarenta regras para APIs web Python que são consistentes, seguras, observáveis e manteníveis entre FastAPI, Django REST Framework e Flask.
Receita
Aplique durante a revisão de design da API antes da implementação. Mapeie as regras para o schema OpenAPI e testes de contrato em CI.
Quando usar isto:
- Projetando uma nova API REST ou RPC
- Revisando pull requests que adicionam endpoints
- Padronizando APIs entre microsserviços
Referência de Regras de API
| # | Área | Regras |
|---|---|---|
| 1-10 | URLs e versionamento | Design de recursos |
| 11-20 | Requisição/resposta | Modelos e validação |
| 21-30 | Erros e segurança | Experiência do cliente |
| 31-40 | Operações e documentação | Prontidão para produção |
Mergulho Profundo
URLs e Versionamento (1-10)
- Substantivos no plural para recursos -
/invoices, não/invoiceou/getInvoices. - Versão no caminho da URL -
/api/v1/invoicespara mudanças que quebram compatibilidade. - Recursos aninhados com no máximo 2 níveis -
/customers/{id}/invoices, sem aninhamento mais profundo. - Use métodos HTTP corretamente - GET para ler, POST para criar, PUT/PATCH para atualizar, DELETE para remover.
- POST para ações -
/invoices/{id}/sendpara operações não-CRUD. - Paginação em todas as listas -
?limit=50&cursor=abcou offset com limite máximo. - Filtragem via parâmetros de query -
?status=paid&since=2026-01-01, sem novos endpoints. - Política consistente de barra final - escolha uma; redirecione a outra (Django: configure
APPEND_SLASH). - Chaves de idempotência em POST - cabeçalho
Idempotency-Keypara operações de pagamento e criação. - HATEOAS opcional - links na resposta quando os clientes são diversos; omita para APIs internas.
Requisição/Resposta (11-20)
- Modelos Pydantic para FastAPI - schemas de requisição e resposta com exemplos.
- Serializadores DRF ou Pydantic para Django - valide a entrada antes da lógica de negócio.
- Datetimes ISO 8601 - UTC com sufixo
Z:2026-07-09T14:30:00Z. - Decimal para dinheiro - nunca
floatpara campos de moeda. - UUIDs para IDs públicos - identificadores opacos; IDs de auto-incremento apenas internos.
- Envelope consistente ou objetos brutos - escolha um estilo por API; documente-o.
- Nomes de campo em snake_case - JSON corresponde às convenções Python, a menos que um contrato externo exija camelCase.
- Especificação OpenAPI gerada - FastAPI automaticamente; DRF com
drf-spectacular; Flask comflask-smorest. - Modelo de resposta exclui internos - não retorne modelos ORM diretamente.
- ETags para GETs cacheados -
If-None-Matchretorna 304 quando inalterado.
Erros e Segurança (21-30)
- RFC 7807 Problem Details -
{"type", "title", "status", "detail", "instance"}. - Códigos de erro consistentes - campo
codelegível por máquina:INVOICE_NOT_FOUND. - 422 para erros de validação - array de detalhes por campo para correções do cliente.
- 401 vs 403 corretamente - 401 não autenticado, 403 autenticado mas não autorizado.
- Limitação de taxa (Rate limiting) - por IP e por token;
429com cabeçalhoRetry-After. - CORS com lista de permissões explícita - nunca
*em produção com credenciais. - Autenticação via token Bearer ou sessão - documente o esquema em
securitySchemesdo OpenAPI. - Limites de tamanho de entrada - tamanho máximo do corpo, upload máximo, comprimento máximo da string de query.
- Sem dados sensíveis em URLs - tokens e senhas apenas em cabeçalhos/corpo.
- Log de auditoria de mutações - quem mudou o quê, quando, em todos os POST/PATCH/DELETE.
Operações e Documentação (31-40)
- Endpoints de saúde e prontidão -
/health(liveness),/ready(dependências ok). - Logging de requisição estruturado - método, caminho, status, duration_ms, request_id.
- Propagação de ID de correlação -
X-Request-IDna entrada e saída. - OpenAPI publicado -
/docsem desenvolvimento; spec exportado como artefato de CI. - Testes de contrato - schemathesis ou Dredd contra OpenAPI em CI.
- Cabeçalhos de deprecação -
Deprecation: trueeSunset:data RFC 8594. - Adições retrocompatíveis - novos campos opcionais ok; remover campos quebra a compatibilidade.
- Rotas assíncronas para I/O -
async defdo FastAPI com drivers de banco de dados assíncronos. - Trabalho em background fora da requisição - Celery, ARQ ou FastAPI BackgroundTasks para e-mails e exportações.
- Teste de carga antes do lançamento - locust ou k6 em staging com volume de dados similar à produção.
Armadilhas
- Retornar objetos ORM - erros de lazy-load e vazamentos de dados. Correção: schemas de resposta explícitos.
- Float para moeda -
0.1 + 0.2 != 0.3. Correção:Decimalonde quer que o dinheiro toque o JSON. - Formas de erro inconsistentes - clientes não conseguem analisar. Correção: um schema de erro imposto por middleware.
- Sem paginação no primeiro dia - mudança que quebra compatibilidade quando os dados crescem. Correção: pague desde o primeiro lançamento.
- Desvio do OpenAPI em relação ao código - a documentação mente. Correção: gere o spec a partir do código; teste de contrato em CI.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| GraphQL | Clientes diversos, grafos complexos | Microsserviço CRUD simples |
| gRPC | Malha de serviços interna | Clientes de navegador públicos |
| Apenas Webhooks | Integração orientada a eventos | Necessidade de requisição/resposta |
FAQs
FastAPI ou Django para nova API?
FastAPI para microsserviços assíncronos. Django para aplicativos com muito admin, ORM e autenticação integrados.
JSON snake_case ou camelCase?
snake_case como padrão para APIs Python. camelCase apenas se o contrato do frontend exigir (use alias).
Como faço o versionamento?
Caminho da URL /v1/ para mudanças que quebram compatibilidade. Mudanças aditivas dentro da mesma versão.
Ações POST no estilo REST ou RPC?
REST para recursos. Ações POST para operações que não se mapeiam a CRUD.
Como documento erros?
Seção responses do OpenAPI por endpoint com exemplo de Problem Details.
FastAPI Síncrono ou Assíncrono?
Assíncrono para I/O-bound com drivers assíncronos. sync def ok com thread pool para ORMs bloqueantes.
Como faço upload de arquivos?
Multipart com limites de tamanho. Armazene em object storage; retorne URL, não bytes do arquivo em JSON.
Chaves de API vs JWT?
JWT para sessões de usuário. Chaves de API para comunicação serviço-a-serviço. Documente escopos para ambos.
Como testo APIs?
pytest + TestClient/httpx. Testes de contrato a partir do OpenAPI. Testes de integração em banco de dados de teste.
Flask em 2026?
Válido para serviços pequenos e extensões. FastAPI é preferível para novas APIs assíncronas.
Relacionados
- 50 Regras Python - regras gerais
- 30 Regras de Segurança - segurança de API
- FastAPI Basics - padrões FastAPI
- Testando APIs Web - testes de API
Versões de Stack: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.