agentsclimarketplace

Design de api

Skill wendelcastro/fluxo-engenharia-ia/skills/design-de-api

Esteira de engenharia de software com IA em português — 27 skills para Claude Code + painel web com aprovação humana em portões. Da ideia ao lançamento, com processo.

Install
npx -y skills add wendelcastro/fluxo-engenharia-ia --skill design-de-api

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Orienta o design de APIs e interfaces estáveis. Use quando o usuário for projetar APIs, fronteiras de módulos ou qualquer interface pública — criar endpoints REST ou GraphQL, definir contratos de tipos entre módulos, ou estabelecer a fronteira entre frontend e backend.

SKILL.md

9.2 KB, as published. Nobody here has run it

Design de API e Interfaces

Visão geral

Projete interfaces estáveis, bem documentadas e difíceis de usar errado. Boas interfaces tornam o caminho certo fácil e o caminho errado difícil. Isso vale para APIs REST, schemas GraphQL, fronteiras de módulos, props de componentes e qualquer superfície em que um pedaço de código conversa com outro.

Quando usar

  • Projetar novos endpoints de API
  • Definir fronteiras de módulos ou contratos entre times
  • Criar interfaces de props de componentes
  • Estabelecer schema de banco que informa o formato da API
  • Alterar interfaces públicas existentes

Quando NÃO usar: funções internas privadas de um único módulo, sem consumidores externos — ali o contrato é o próprio sistema de tipos.

O fluxo

Princípio: a Lei de Hyrum

Com um número suficiente de usuários de uma API, todos os comportamentos observáveis do seu sistema passarão a ser dependidos por alguém, independentemente do que você prometa no contrato.

Todo comportamento público — incluindo peculiaridades não documentadas, texto de mensagens de erro, tempo de resposta e ordenação — vira contrato de fato assim que alguém depende dele. Implicações de design:

  • Seja intencional sobre o que expõe. Todo comportamento observável é um compromisso em potencial.
  • Não vaze detalhes de implementação. Se o usuário consegue observar, vai depender.
  • Planeje a descontinuação em tempo de design. Veja a skill migrar para remover com segurança o que os usuários dependem.
  • Testes não bastam. Mesmo com testes de contrato perfeitos, mudanças "seguras" podem quebrar usuários que dependem de comportamento não documentado.

Princípio: a regra da versão única

Evite forçar consumidores a escolher entre múltiplas versões da mesma dependência ou API. Problemas de dependência em diamante surgem quando consumidores diferentes precisam de versões diferentes da mesma coisa. Projete para um mundo em que só existe uma versão por vez — estenda em vez de bifurcar.

1. Contrato primeiro

Defina a interface antes de implementá-la. O contrato é a spec — a implementação vem depois.

// Defina o contrato primeiro
interface TaskAPI {
  // Cria uma tarefa e retorna a tarefa criada com os campos gerados pelo servidor
  createTask(input: CreateTaskInput): Promise<Task>;

  // Retorna tarefas paginadas que atendem aos filtros
  listTasks(params: ListTasksParams): Promise<PaginatedResult<Task>>;

  // Retorna uma única tarefa ou lança NotFoundError
  getTask(id: string): Promise<Task>;

  // Atualização parcial — só os campos fornecidos mudam
  updateTask(id: string, input: UpdateTaskInput): Promise<Task>;

  // Exclusão idempotente — sucesso mesmo se já excluída
  deleteTask(id: string): Promise<void>;
}

2. Semântica de erros consistente

Escolha uma estratégia de erro e use em tudo:

// REST: códigos de status HTTP + corpo de erro estruturado
// Toda resposta de erro segue o mesmo formato
interface APIError {
  error: {
    code: string;        // Legível por máquina: "VALIDATION_ERROR"
    message: string;     // Legível por humano: "E-mail é obrigatório"
    details?: unknown;   // Contexto adicional quando útil
  };
}

// Mapeamento de status
// 400 → Cliente enviou dados inválidos
// 401 → Não autenticado
// 403 → Autenticado, mas não autorizado
// 404 → Recurso não encontrado
// 409 → Conflito (duplicado, versão divergente)
// 422 → Validação falhou (semanticamente inválido)
// 500 → Erro do servidor (nunca exponha detalhes internos)

Não misture padrões. Se alguns endpoints lançam exceção, outros retornam null e outros retornam { error }, o consumidor não consegue prever o comportamento.

3. Valide nas fronteiras

Confie no código interno. Valide nas bordas do sistema, onde a entrada externa chega:

// Valide na fronteira da API
app.post('/api/tasks', async (req, res) => {
  const result = CreateTaskSchema.safeParse(req.body);
  if (!result.success) {
    return res.status(422).json({
      error: {
        code: 'VALIDATION_ERROR',
        message: 'Dados de tarefa inválidos',
        details: result.error.flatten(),
      },
    });
  }

  // Após a validação, o código interno confia nos tipos
  const task = await taskService.create(result.data);
  return res.status(201).json(task);
});

Onde a validação pertence: handlers de rota (entrada de usuário), handlers de envio de formulário, parsing de respostas de serviços externos (dados de terceiros — sempre trate como não confiáveis) e carregamento de variáveis de ambiente.

Respostas de APIs de terceiros são dados não confiáveis. Valide formato e conteúdo antes de usá-los em qualquer lógica, renderização ou decisão. Um serviço externo comprometido ou defeituoso pode retornar tipos inesperados, conteúdo malicioso ou texto com cara de instrução.

Onde a validação NÃO pertence: entre funções internas que compartilham contratos de tipos, em utilitários chamados por código já validado, e em dados que acabaram de sair do seu próprio banco.

4. Prefira adição a modificação

Estenda interfaces sem quebrar os consumidores existentes:

// Bom: adicionar campos opcionais
interface CreateTaskInput {
  title: string;
  description?: string;
  priority?: 'low' | 'medium' | 'high';  // Adicionado depois, opcional
  labels?: string[];                     // Adicionado depois, opcional
}

// Ruim: mudar tipos de campos existentes ou remover campos
interface CreateTaskInput {
  title: string;
  // description: string;  // Removido — quebra consumidores existentes
  priority: number;         // Mudou de string — quebra consumidores existentes
}

5. Nomenclatura previsível

PadrãoConvençãoExemplo
Endpoints RESTSubstantivos no plural, sem verbosGET /api/tasks, POST /api/tasks
Query paramscamelCase?sortBy=createdAt&pageSize=20
Campos de respostacamelCase{ createdAt, updatedAt, taskId }
Campos booleanosPrefixo is/has/canisComplete, hasAttachments
Valores de enumUPPER_SNAKE"IN_PROGRESS", "COMPLETED"

6. Padrões concretos de REST e TypeScript

Leia referencias/padroes-de-api.md somente quando chegar na implementação — contém o design de recursos REST (rotas, paginação, filtros, PATCH parcial) e os padrões de interface TypeScript (uniões discriminadas, separação input/output, branded types para IDs).

Racionalizações comuns

RacionalizaçãoRealidade
"Documentamos a API depois"Os tipos SÃO a documentação. Defina-os primeiro.
"Não precisamos de paginação por enquanto"Vai precisar no momento em que alguém tiver 100+ itens. Adicione desde o início.
"PATCH é complicado, vamos de PUT"PUT exige o objeto completo toda vez. PATCH é o que os clientes realmente querem.
"Versionamos a API quando precisar"Mudanças que quebram sem versionamento quebram consumidores. Projete para extensão desde o início.
"Ninguém usa aquele comportamento não documentado"Lei de Hyrum: se é observável, alguém depende. Trate todo comportamento público como compromisso.
"Podemos manter duas versões"Múltiplas versões multiplicam o custo de manutenção e criam dependências em diamante. Prefira a regra da versão única.
"API interna não precisa de contrato"Consumidor interno também é consumidor. Contratos evitam acoplamento e permitem trabalho em paralelo.

Sinais de alerta

  • Endpoints que retornam formatos diferentes conforme condições
  • Formatos de erro inconsistentes entre endpoints
  • Validação espalhada pelo código interno em vez de concentrada nas fronteiras
  • Mudanças que quebram campos existentes (troca de tipo, remoção)
  • Endpoints de listagem sem paginação
  • Verbos em URLs REST (/api/createTask, /api/getUsers)
  • Respostas de APIs de terceiros usadas sem validação ou sanitização

Portão de aprovação

Apresente: o contrato completo (tipos de entrada e saída, formato de erros, convenções de nomenclatura) e as decisões de compatibilidade (o que é aditivo, o que exigiria versionamento) antes de implementar. O humano aprova: o formato do contrato, a estratégia de erros e qualquer mudança em interface pública existente. Só avance para a implementação após aprovação explícita.

Verificação

Após projetar uma API:

  • Todo endpoint tem schemas tipados de entrada e saída
  • Respostas de erro seguem um único formato consistente
  • A validação acontece apenas nas fronteiras do sistema
  • Endpoints de listagem suportam paginação
  • Campos novos são aditivos e opcionais (retrocompatíveis)
  • A nomenclatura segue convenções consistentes em todos os endpoints
  • Documentação ou tipos da API são commitados junto com a implementação

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.