Gerador de Documentação de API
Extrai documentação de API a partir do código existente de manipuladores de rotas. Lê seu código-fonte, infere esquemas e produz especificações OpenAPI, tipos TypeScript e exemplos curl executáveis — não a partir da intenção de design, mas da implementação real.
Gatilhos de Ativação
Ativar em: "gerar docs da API", "OpenAPI a partir do código", "documentar endpoints", "referência da API", "geração swagger", "documentação de endpoint", "criar tipos de API", "exemplos curl para API"
NÃO para: Design de API do zero --> api-architect | Criação de OpenAPI sem código-fonte --> openapi-spec-writer | Testes de API --> test-automation-expert
Capacidades Principais
- Extrair definições de rotas de Express, Next.js App Router, Next.js Pages API Routes, Fastify e Hono handlers
- Inferir esquemas de requisição/resposta a partir de tipos TypeScript, esquemas Zod ou validação em tempo de execução
- Gerar especificações OpenAPI 3.0/3.1 com parâmetros de caminho precisos, strings de consulta e corpos de requisição
- Produzir definições de tipo TypeScript correspondentes ao contrato real da API
- Criar exemplos curl para cada endpoint com dados de amostra realistas
- Documentar requisitos de autenticação rastreando cadeias de middleware
- Identificar configuração de limite de taxa e documentar limites por endpoint
- Catalogar respostas de erro analisando padrões de throw/return nos handlers
- Detectar endpoints não documentados (rotas que existem, mas não têm JSDoc ou esquema)
Detecção de Framework
Antes de gerar qualquer coisa, identifique o framework. A estratégia de extração difere significativamente.
Express / Express-like
Sinais: app.get(), router.post(), express.Router()
Fonte da rota: app._router.stack ou arquivos de roteador explícitos
Cadeia de middleware: a ordem de app.use() é importante para detecção de autenticação
Procure por padrões de registro de rota:
router.get('/users/:id', authenticate, getUser)-- middleware antes do handler significa autenticação necessáriaapp.use('/api/v1', rateLimiter({ max: 100 }), apiRouter)-- limitador de taxa aplicado a uma subárvore
Next.js App Router
Sinais: arquivos route.ts exportando GET, POST, PUT, DELETE, PATCH
Fonte da rota: Convenção de sistema de arquivos em app/api/
Cadeia de middleware: middleware.ts nos limites de diretório
Parâmetros de caminho vêm de nomes de pasta: app/api/users/[id]/route.ts --> /api/users/{id}
Next.js Pages API Routes
Sinais: pages/api/**/*.ts com export default handler
Fonte da rota: Convenção de sistema de arquivos
Roteamento de método: switch req.method dentro do handler
Fastify
Sinais: fastify.get(), fastify.route(), propriedade schema nas opções de rota
Fonte da rota: Registro de plugin com fastify.register()
Esquema: Rotas Fastify geralmente têm JSON Schema — extraia e converta
Fastify é o framework mais fácil de documentar porque as rotas frequentemente declaram seus próprios esquemas. Priorize a extração de schema.body, schema.response e schema.querystring existentes antes de inferir.
Hono
Sinais: app.get(), app.post(), Hono(), zValidator()
Fonte da rota: Encadeamento de métodos na instância Hono
Validação: baseada em Zod via middleware zValidator
Hono com zValidator fornece esquemas Zod diretamente. Converta Zod --> JSON Schema --> OpenAPI schema.
Processo de Extração
Passo 1: Descobrir Rotas
Escaneie o projeto em busca de registro de rotas. Não confie em um único ponto de entrada — frameworks geralmente dividem rotas entre arquivos.
# Express: encontre arquivos de roteador
grep -rl "express.Router\|app.get\|app.post\|router\." src/ --include="*.ts" --include="*.js"
# Next.js App Router: encontre manipuladores de rota
find src/app/api -name "route.ts" -o -name "route.js"
# Next.js Pages: encontre rotas de API
find src/pages/api -name "*.ts" -o -name "*.js"
# Fastify: encontre registros de rota
grep -rl "fastify\.\(get\|post\|put\|delete\|route\)" src/ --include="*.ts"
# Hono: encontre definições de rota
grep -rl "app\.\(get\|post\|put\|delete\|patch\)" src/ --include="*.ts"
Passo 2: Extrair Esquemas
Para cada rota, identifique as formas de requisição e resposta.
Ordem de prioridade para fontes de esquema:
- Esquemas de validação explícitos (Zod/Joi/Yup) (maior confiança)
- Anotações de tipo TypeScript em requisição/resposta
- Declarações JSON Schema (Fastify)
- Anotações JSDoc @param / @returns
- Inferência em tempo de execução a partir da construção da resposta (menor confiança — sinalizar como aproximado)
Ao usar inferência em tempo de execução (opção 5), sempre marque o esquema com x-inferred: true na saída OpenAPI para que os consumidores saibam que pode estar incompleto.
Passo 3: Rastrear Autenticação
Percorra a cadeia de middleware para cada rota para determinar os requisitos de autenticação:
- Sem middleware de autenticação: Marcar como
security: [](público) - Middleware de token Bearer: Marcar como
security: [{ bearerAuth: [] }] - Middleware de chave de API: Marcar como
security: [{ apiKeyAuth: [] }] - Autenticação de sessão/cookie: Marcar como
security: [{ cookieAuth: [] }] - Múltiplas opções de autenticação: Listar todas como alternativas no array security
Passo 4: Catalogar Erros
Leia cada handler e liste cada resposta de erro:
res.status(400).json(...)outhrow new BadRequestError(...)--> esquema de resposta 400res.status(401)--> 401 (incluir se middleware de autenticação presente mesmo sem throw explícito)res.status(404)--> 404res.status(409)--> 409 (conflito, comum em operações de criação)res.status(422)--> 422 (falha de validação)res.status(429)--> 429 (limite de taxa, incluir se middleware de limitador de taxa detectado)res.status(500)--> 500 (sempre incluir como possibilidade)
Passo 5: Gerar Saídas
Produza três artefatos:
- Especificação OpenAPI (YAML, não JSON — mais legível, mais fácil de fazer diff)
- Tipos TypeScript (arquivo
.d.tsindependente com todos os tipos de requisição/resposta) - Exemplos curl (um por endpoint, com cabeçalhos e payloads de amostra)
Pontos de Decisão
Quando o código-fonte NÃO tem esquemas de validação
Se os handlers aceitam req.body bruto sem validação Zod/Joi, você deve inferir tipos a partir do uso. Procure por:
- Padrões de acesso a propriedades:
req.body.name,req.body.email-->{ name: string, email: string } - Destruturação:
const { name, email } = req.body--> mesma inferência - Chamadas de inserção no banco de dados:
db.users.create({ name: body.name })--> cruzar referência com esquema do BD, se disponível
Sinalize toda a especificação com um aviso: x-schemas-inferred: true no nível de informação.
Quando as rotas usam segmentos de caminho dinâmicos
- Express:
:id--> OpenAPI{id} - Next.js:
[id]--> OpenAPI{id} - Next.js catch-all:
[...slug]--> OpenAPI{slug}com nota sobre comportamento de array - Fastify:
:id--> OpenAPI{id} - Hono:
:id--> OpenAPI{id}
Quando a forma da resposta varia por código de status
Documente cada código de status com seu próprio esquema. Não mescle 200 e 201 em um único esquema se eles diferirem. Padrão comum:
responses:
'200':
description: Usuário encontrado
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: Usuário não encontrado
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Quando os limites de taxa diferem por endpoint
Documente limites de taxa usando extensões OpenAPI:
x-rate-limit:
requests: 100
window: 60s
scope: por-chave-de-api
Se o limitador de taxa for global (aplicado uma vez no nível do aplicativo), documente-o na seção info de nível superior. Se por rota, documente em cada operação.
Geração de Tipo TypeScript
Gere tipos que correspondam exatamente à especificação OpenAPI. Use tipos marcados para IDs quando o código-fonte os usar.
// Gerado a partir da especificação OpenAPI — não edite manualmente
export interface CreateUserRequest {
name: string;
email: string;
role?: 'admin' | 'member' | 'viewer';
}
export interface CreateUserResponse {
id: string;
name: string;
email: string;
role: 'admin' | 'member' | 'viewer';
createdAt: string; // ISO 8601
}
export interface ErrorResponse {
error: {
code: string;
message: string;
details?: Array<{
field: string;
issue: string;
}>;
};
}
export interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
perPage: number;
total: number;
hasMore: boolean;
};
}
Geração de Exemplo Curl
Gere um curl por endpoint. Use dados realistas, mas obviamente falsos.
# GET /api/users/:id -- Buscar um único usuário
curl -X GET https://api.example.com/api/users/usr_abc123 \
-H "Authorization: Bearer sk_test_..." \
-H "Accept: application/json"
# POST /api/users -- Criar um novo usuário
curl -X POST https://api.example.com/api/users \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "[email protected]",
"role": "member"
}'
# GET /api/users -- Listar usuários com paginação
curl -X GET "https://api.example.com/api/users?page=1&perPage=20&role=admin" \
-H "Authorization: Bearer sk_test_..." \
-H "Accept: application/json"
Regras para exemplos curl:
- Sempre incluir a URL completa (usar
https://api.example.comcomo base) - Incluir todos os cabeçalhos necessários
- Usar
-dcom JSON formatado para corpos de requisição - Colocar URLs que contêm parâmetros de consulta entre aspas
- Mostrar o método HTTP explicitamente mesmo para GET
- Usar
sk_test_...para tokens de autenticação (obviamente falsos) - Usar valores de campo realistas, não "string" ou "test"
Anti-Padrões
1. Documentar APIs Aspiracionais
Sintoma: Especificação descreve endpoints que ainda não existem no código Correção: Documente apenas o que o código realmente implementa. Se um endpoint planejado está em comentários ou em um arquivo de especificação, mas não em handlers, exclua-o.
2. Ignorar Efeitos Colaterais de Middleware
Sintoma: Documentação diz que o endpoint é público quando na verdade requer autenticação através de um middleware pai
Correção: Rastreie a cadeia completa de middleware da raiz do aplicativo até o handler. Um router.use(auth) acima da definição da rota significa que todas as rotas abaixo requerem autenticação.
3. Assumir a Forma do Corpo da Requisição
Sintoma: Documentar req.body como any ou object porque não há validação
Correção: Inferir a partir do uso (acesso a propriedades, destruturação, chamadas ao banco de dados). Marcar como x-inferred: true. Recomendar adicionar validação Zod.
4. Documentação de Erro Genérica
Sintoma: Todo endpoint lista o mesmo "400 Bad Request" genérico sem detalhes Correção: Leia os caminhos de erro de cada handler. Documente os códigos de erro e mensagens específicos retornados. Diferentes falhas de validação devem mostrar diferentes exemplos de resposta.
5. Documentos Gerados Desatualizados
Sintoma: Especificação foi gerada uma vez e nunca atualizada conforme o código mudou
Correção: Gerar em um caminho conhecido (docs/openapi.yaml). Adicionar uma verificação de CI que regenera e faz diff contra a especificação confirmada. Se divergirem, falhe a build.
6. Documentação de Paginação Ausente
Sintoma: Endpoints de lista documentados sem esquemas de parâmetros de consulta para paginação
Correção: Se o handler suporta page, limit, cursor, offset ou parâmetros similares, documente-os com valores padrão e máximos.
7. Uploads de Arquivo Não Documentados
Sintoma: Endpoints multipart/form-data documentados como JSON
Correção: Detecte multer, formidable, busboy ou manipulação de arquivo nativa do framework. Use o tipo de conteúdo multipart/form-data com esquema binário adequado.
Lista de Verificação de Qualidade
[ ] Cada manipulador de rota no código-fonte tem uma operação OpenAPI correspondente
[ ] Parâmetros de caminho correspondem entre código e especificação (sem incompatibilidades :id vs {userId})
[ ] Esquemas de corpo de requisição cobrem todos os campos obrigatórios e opcionais
[ ] Esquemas de resposta correspondem à estrutura JSON real (verificado lendo o retorno do handler)
[ ] Requisitos de autenticação correspondem à análise da cadeia de middleware
[ ] Informações de limite de taxa documentadas onde existe middleware de limitação de taxa
[ ] Respostas de erro catalogadas a partir de declarações reais de throw/return nos handlers
[ ] Exemplos curl executam com sucesso contra uma instância em execução
[ ] Tipos TypeScript compilam sem erros
[ ] Nenhum esquema x-inferred deixado não documentado (cada um sinalizado tem um TODO para validação adequada)
[ ] Parâmetros de paginação documentados com valores padrão e máximos
[ ] Endpoints de upload de arquivo usam tipo de conteúdo multipart/form-data
[ ] Especificação OpenAPI valida com lint spectral ou swagger-cli
[ ] Especificação gerada confirmada em um caminho conhecido para diff de CI
Artefatos de Saída
docs/openapi.yaml-- Especificação OpenAPI 3.0/3.1 completadocs/api-types.d.ts-- Definições de tipo TypeScript para todas as formas de requisição/respostadocs/api-examples.sh-- Exemplos curl executáveis para cada endpointdocs/api-coverage.md-- Relatório listando rotas documentadas vs não documentadas
Validação
# Lint da especificação OpenAPI gerada
npx @stoplight/spectral-cli lint docs/openapi.yaml
# Validar estrutura da especificação
npx swagger-cli validate docs/openapi.yaml
# Gerar cliente TypeScript para verificar se os tipos compilam
npx openapi-typescript docs/openapi.yaml -o /tmp/api-check.d.ts
tsc --noEmit /tmp/api-check.d.ts
# Diff contra a última especificação confirmada (verificação de CI)
diff <(cat docs/openapi.yaml) <(npx tsx scripts/generate-api-docs.ts --stdout) && echo "Especificação está atualizada" || echo "Especificação está desatualizada"
Cobre: Geração OpenAPI | Extração de tipos TypeScript | Criação de exemplos Curl | Documentação de autenticação | Documentação de limite de taxa | Catalogação de códigos de erro
Use com: api-architect (projetar primeiro, documentar depois) | openapi-spec-writer (criação manual) | test-automation-expert (testes de contrato contra especificação gerada)