9 min leitura • Guide 752 of 877
Melhores Práticas de Desenvolvimento de API
APIs são contratos entre sistemas. GitScrum ajuda equipes a planejar, rastrear e entregar trabalho de API com documentação e testes adequados.
Planejamento de API
Histórias de API no GitScrum
ESTRUTURA DE HISTÓRIA DE API:
┌─────────────────────────────────────────────────────────────┐
│ API-123: Criar Endpoint de Usuário │
├─────────────────────────────────────────────────────────────┤
│ │
│ Como um consumidor de API │
│ Eu posso criar um novo usuário via POST /api/v1/users │
│ Para que eu possa integrar usuários programaticamente │
│ │
│ ═══════════════════════════════════════════════════════════ │
│ │
│ ESPECIFICAÇÃO DE ENDPOINT: │
│ │
│ Método: POST │
│ Caminho: /api/v1/users │
│ Auth: Token Bearer requerido │
│ │
│ Corpo da Requisição: │
│ { │
│ "email": "user@example.com", │
│ "name": "John Doe", │
│ "role": "member" │
│ } │
│ │
│ Resposta de Sucesso (201): │
│ { │
│ "id": "usr_abc123", │
│ "email": "user@example.com", │
│ "name": "John Doe", │
│ "role": "member", │
│ "created_at": "2024-01-15T10:30:00Z" │
│ } │
│ │
│ Respostas de Erro: │
│ 400 - Input inválido (campo faltando, formato inválido) │
│ 401 - Autenticação requerida │
│ 403 - Permissões insuficientes │
│ 409 - Email já existe │
│ │
│ ═══════════════════════════════════════════════════════════ │
│ │
│ CRITÉRIOS DE ACEITAÇÃO: │
│ ☐ Endpoint aceita dados válidos de usuário │
│ ☐ Retorna 201 com usuário criado │
│ ☐ Valida formato de email │
│ ☐ Rejeita emails duplicados (409) │
│ ☐ Requer autenticação │
│ ☐ Documentação atualizada │
│ ☐ Testes cobrem caminho feliz e erros │
└─────────────────────────────────────────────────────────────┘
Checklist de Design de API
PRINCÍPIOS DE DESIGN DE API:
┌─────────────────────────────────────────────────────────────┐
│ │
│ CONVENÇÕES DE NOMENCLATURA: │
│ │
│ ✅ Recursos são substantivos, plurais: │
│ /users, /projects, /tasks │
│ │
│ ✅ Use kebab-case para múltiplas palavras: │
│ /project-members, /time-entries │
│ │
│ ✅ Aninhe para relacionamentos: │
│ /projects/{id}/tasks │
│ /users/{id}/notifications │
│ │
│ ❌ Não use verbos no caminho: │
│ /getUsers → GET /users │
│ /createProject → POST /projects │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ MÉTODOS HTTP: │
│ │
│ GET - Recuperar recurso(s) │
│ POST - Criar novo recurso │
│ PUT - Substituir recurso inteiro │
│ PATCH - Atualizar parte do recurso │
│ DELETE - Remover recurso │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ CÓDIGOS DE STATUS: │
│ │
│ 200 OK - GET/PUT/PATCH bem-sucedido │
│ 201 Created - POST bem-sucedido │
│ 204 No Content - DELETE bem-sucedido │
│ 400 Bad Request - Input inválido │
│ 401 Unauthorized - Sem auth │
│ 403 Forbidden - Sem permissão │
│ 404 Not Found - Recurso não existe │
│ 409 Conflict - Duplicado/conflito │
│ 422 Unprocessable - Validação falhou │
│ 500 Server Error - Nossa culpa │
└─────────────────────────────────────────────────────────────┘
Versionamento de API
Estratégia de Versão
ABORDAGENS DE VERSIONAMENTO DE API:
┌─────────────────────────────────────────────────────────────┐
│ │
│ OPÇÃO 1: CAMINHO URL (Recomendado) │
│ │
│ /api/v1/users │
│ /api/v2/users │
│ │
│ Prós: Claro, fácil de rotear, cacheável │
│ Contras: URLs mudam entre versões │
│ │
│ OPÇÃO 2: HEADER │
│ │
│ Accept: application/vnd.api.v1+json │
│ │
│ Prós: URLs limpos │
│ Contras: Menos descobribilidade, mais difícil de testar │
│ │
│ OPÇÃO 3: PARÂMETRO QUERY │
│ │
│ /api/users?version=1 │
│ │
│ Prós: Simples │
│ Contras: Pode ser cacheado incorretamente │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ REGRAS DE VERSIONAMENTO: │
│ │
│ VERSÃO MAJOR (v1 → v2): │
│ • Mudanças quebradoras │
│ • Endpoints removidos │
│ • Estrutura de resposta mudada │
│ │
│ VERSÃO MINOR (rastreado no changelog): │
│ • Novos endpoints │
│ • Novos campos opcionais │
│ • Mudanças não quebradoras │
│ │
│ MANTENHA MÚLTIPLAS VERSÕES: │
│ v1: Depreciado, data de sunset anunciada │
│ v2: Versão estável atual │
│ v3: Beta/preview (opcional) │
└─────────────────────────────────────────────────────────────┘
Mudanças Quebradoras
GERENCIANDO MUDANÇAS QUEBRADORAS:
┌─────────────────────────────────────────────────────────────┐
│ │
│ O QUE É UMA MUDANÇA QUEBRADORA: │
│ │
│ ✅ QUEBRADORA: │
│ • Removendo um endpoint │
│ • Removendo um campo da resposta │
│ • Mudando tipo de campo (string → object) │
│ • Mudando status requerido/opcional │
│ • Mudando método de autenticação │
│ │
│ ✅ NÃO QUEBRADORA: │
│ • Adicionando novo endpoint │
│ • Adicionando novo campo à resposta │
│ • Adicionando novo parâmetro opcional │
│ • Mudando texto da mensagem de erro │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ PROCESSO DE DEPRECIAÇÃO: │
│ │
│ 1. ANUNCIE │
│ "v1 será depreciada em 6 meses" │
│ Adicione avisos de depreciação às respostas │
│ │
│ 2. SUPORTE TRANSIÇÃO │
│ Execute v1 e v2 simultaneamente │
│ Forneça guia de migração │
│ │
│ 3. MONITORE USO │
│ Rastreie chamadas de API v1 │
│ Notifique consumidores ativos de v1 │
│ │
│ 4. SUNSET │
│ Aviso final 30 dias antes │
│ Desligue v1, retorne 410 Gone │
│ │
│ RASTREAMENTO GITSCRUM: │
│ Label: breaking-change │
│ Inclua notas de migração na história │
│ Vincule a integrações afetadas │
└─────────────────────────────────────────────────────────────┘
Documentação de API
Padrões de Documentação
REQUISITOS DE DOCUMENTAÇÃO DE API:
┌─────────────────────────────────────────────────────────────┐
│ │
│ TODO ENDPOINT PRECISA: │
│ │
│ 1. VISÃO GERAL │
│ O que este endpoint faz? │
│ Quando você o usaria? │
│ │
│ 2. REQUEST │
│ • Método e caminho │
│ • Headers requeridos │
│ • Parâmetros de caminho │
│ • Parâmetros de query │
│ • Schema de corpo de request │
│ • Exemplo de request │
│ │
│ 3. RESPONSE │
│ • Schema de resposta de sucesso │
│ • Exemplo de resposta de sucesso │
│ • Todas possíveis respostas de erro │
│ • Exemplos de respostas de erro │
│ │
│ 4. EXEMPLOS DE CÓDIGO │
│ Exemplos cURL, JavaScript, Python │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ FERRAMENTAS DE DOCUMENTAÇÃO: │
│ │
│ OpenAPI/Swagger: │
│ • Defina API em YAML/JSON │
│ • Auto-gerar docs │
│ • Teste interativo │
│ │
│ Mantenha docs com código: │
│ • /docs/api/ no repositório │
│ • Atualizações com PRs │
│ • Controle de versão │
│ │
│ DEFINIÇÃO DE PRONTO: │
│ ☐ Endpoint funciona │
│ ☐ Testes escritos │
│ ☐ Documentação atualizada │
│ ☐ Entrada de changelog adicionada │
└─────────────────────────────────────────────────────────────┘
Teste de API
Categorias de Teste
ESTRATÉGIA DE TESTE DE API:
┌─────────────────────────────────────────────────────────────┐
│ │
│ TESTES UNITÁRIOS: │
│ Teste funções/handlers individuais │
│ • Lógica de validação │
│ • Lógica de negócio │
│ • Transformações de dados │
│ │
│ TESTES DE INTEGRAÇÃO: │
│ Teste comportamento de endpoint │
│ • Fluxo Request → Response │
│ • Interações com banco de dados │
│ • Chamadas de serviço externo (mocked) │
│ │
│ TESTES DE CONTRATO: │
│ Verifique se API combina com especificação │
│ • Resposta combina com spec OpenAPI │
│ • Mudanças quebradoras capturadas │
│ │
│ TESTES E2E: │
│ Teste fluxos completos de usuário │
│ • Criar usuário → Criar projeto → Adicionar tarefa │
│ • Banco de dados real, serviços reais │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ COBERTURA DE TESTE PARA ENDPOINTS: │
│ │
│ ☐ Caminho feliz (caso de sucesso) │
│ ☐ Erros de validação (400) │
│ ☐ Autenticação requerida (401) │
│ ☐ Permissão negada (403) │
│ ☐ Não encontrado (404) │
│ ☐ Conflito/duplicado (409) │
│ ☐ Rate limiting (429) │
│ ☐ Casos extremos (input vazio, valores max) │
│ │
│ CRITÉRIOS DE ACEITAÇÃO: │
│ Testes devem cobrir todas respostas documentadas │
└─────────────────────────────────────────────────────────────┘
Tratamento de Erros
Erros Consistentes
PADRÕES DE RESPOSTA DE ERRO:
┌─────────────────────────────────────────────────────────────┐
│ │
│ ESTRUTURA DE RESPOSTA DE ERRO: │
│ │
│ { │
│ "error": { │
│ "code": "validation_error", │
│ "message": "Input inválido fornecido", │
│ "details": [ │
│ { │
│ "field": "email", │
│ "message": "Formato de email inválido" │
│ }, │
│ { │
│ "field": "name", │
│ "message": "Nome é requerido" │
│ } │
│ ], │
│ "request_id": "req_abc123" │
│ } │
│ } │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ CÓDIGOS DE ERRO (Legíveis por máquina): │
│ │
│ validation_error - Input inválido │
│ authentication_error - Sem/auth inválida │
│ authorization_error - Sem permissão │
│ not_found - Recurso não existe │
│ conflict - Duplicado/conflito │
│ rate_limited - Muitas requisições │
│ server_error - Erro interno │
│ │
│ PRINCÍPIOS: │
│ │
│ • Códigos de erro legíveis por máquina │
│ • Mensagens legíveis por humanos │
│ • Detalhes de nível de campo quando relevante │
│ • ID de request para debugging │
│ • Não exponha detalhes internos │
│ • Estrutura consistente através de todos endpoints │
└─────────────────────────────────────────────────────────────┘