Communitygithub.com

design-de-api

Padrões de design de API REST incluindo nomenclatura de recursos, códigos de status, paginação, filtragem, respostas de erro, versionamento e limitação de taxa para APIs de produção. Use ao projetar ou revisar endpoints REST, nomes de recursos, códigos de status, paginação ou versionamento.

O que é design-de-api?

Este skill orienta o design de APIs REST consistentes e amigáveis para desenvolvedores, cobrindo desde a nomenclatura de recursos até estratégias de versionamento. Ele é útil para desenvolvedores que estão projetando novos endpoints, revisando contratos de API ou implementando recursos como paginação, filtragem e tratamento de erros. O skill suporta as principais plataformas de agentes de IA (Claude Code, Cursor, Codex) e define convenções claras para estrutura de URLs (plural, kebab-case, sem verbos), uso semântico de métodos HTTP e códigos de status, e formatos de resposta consistentes. Também oferece orientação prática sobre paginação baseada em offset versus cursor, sintaxe de filtragem e ordenação, autenticação via token e limitação de taxa, com exemplos de implementação em TypeScript, Python e Go. O conteúdo é baseado em documentação detalhada (SKILL.md) que serve como referência direta para o agente durante tarefas de design ou revisão de API.

Funciona com~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/api-design

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Design de API

Convenções e melhores práticas para projetar APIs REST consistentes e amigáveis para desenvolvedores.

Quando Ativar

  • Projetando novos endpoints de API
  • Revisando contratos de API existentes
  • Adicionando paginação, filtragem ou ordenação
  • Implementando tratamento de erros para APIs
  • Planejando estratégia de versionamento de API
  • Construindo APIs públicas ou voltadas para parceiros

Design de Recursos

Estrutura de URL

# Recursos são substantivos, plurais, minúsculos, kebab-case
GET    /api/v1/users
GET    /api/v1/users/:id
POST   /api/v1/users
PUT    /api/v1/users/:id
PATCH  /api/v1/users/:id
DELETE /api/v1/users/:id

# Sub-recursos para relacionamentos
GET    /api/v1/users/:id/orders
POST   /api/v1/users/:id/orders

# Ações que não mapeiam para CRUD (use verbos com moderação)
POST   /api/v1/orders/:id/cancel
POST   /api/v1/auth/login
POST   /api/v1/auth/refresh

Regras de Nomenclatura

# BOM
/api/v1/team-members          # kebab-case para recursos com várias palavras
/api/v1/orders?status=active  # parâmetros de consulta para filtragem
/api/v1/users/123/orders      # recursos aninhados para propriedade

# RUIM
/api/v1/getUsers              # verbo na URL
/api/v1/user                  # singular (use plural)
/api/v1/team_members          # snake_case em URLs
/api/v1/users/123/getOrders   # verbo em recurso aninhado

Métodos HTTP e Códigos de Status

Semântica dos Métodos

MétodoIdempotenteSeguroUso Para
GETSimSimRecuperar recursos
POSTNãoNãoCriar recursos, acionar ações
PUTSimNãoSubstituição completa de um recurso
PATCHNão*NãoAtualização parcial de um recurso
DELETESimNãoRemover um recurso

*PATCH pode ser tornado idempotente com implementação adequada

Referência de Códigos de Status

# Sucesso
200 OK                    — GET, PUT, PATCH (com corpo de resposta)
201 Created               — POST (incluir cabeçalho Location)
204 No Content            — DELETE, PUT (sem corpo de resposta)

# Erros do Cliente
400 Bad Request           — Falha de validação, JSON malformado
401 Unauthorized          — Autenticação ausente ou inválida
403 Forbidden             — Autenticado, mas não autorizado
404 Not Found             — Recurso não existe
409 Conflict              — Entrada duplicada, conflito de estado
422 Unprocessable Entity  — Semanticamente inválido (JSON válido, dados ruins)
429 Too Many Requests     — Limite de taxa excedido

# Erros do Servidor
500 Internal Server Error — Falha inesperada (nunca exponha detalhes)
502 Bad Gateway           — Serviço upstream falhou
503 Service Unavailable   — Sobrecarga temporária, incluir Retry-After

Erros Comuns

# RUIM: 200 para tudo
{ "status": 200, "success": false, "error": "Não encontrado" }

# BOM: Use códigos de status HTTP semanticamente
HTTP/1.1 404 Not Found
{ "error": { "code": "not_found", "message": "Usuário não encontrado" } }

# RUIM: 500 para erros de validação
# BOM: 400 ou 422 com detalhes no nível do campo

# RUIM: 200 para recursos criados
# BOM: 201 com cabeçalho Location
HTTP/1.1 201 Created
Location: /api/v1/users/abc-123

Formato de Resposta

Resposta de Sucesso

{
  "data": {
    "id": "abc-123",
    "email": "[email protected]",
    "name": "Alice",
    "created_at": "2025-01-15T10:30:00Z"
  }
}

Resposta de Coleção (com Paginação)

{
  "data": [
    { "id": "abc-123", "name": "Alice" },
    { "id": "def-456", "name": "Bob" }
  ],
  "meta": {
    "total": 142,
    "page": 1,
    "per_page": 20,
    "total_pages": 8
  },
  "links": {
    "self": "/api/v1/users?page=1&per_page=20",
    "next": "/api/v1/users?page=2&per_page=20",
    "last": "/api/v1/users?page=8&per_page=20"
  }
}

Resposta de Erro

{
  "error": {
    "code": "validation_error",
    "message": "Falha na validação da requisição",
    "details": [
      {
        "field": "email",
        "message": "Deve ser um endereço de email válido",
        "code": "invalid_format"
      },
      {
        "field": "age",
        "message": "Deve estar entre 0 e 150",
        "code": "out_of_range"
      }
    ]
  }
}

Variantes do Invólucro de Resposta

// Opção A: Invólucro com wrapper de dados (recomendado para APIs públicas)
interface ApiResponse<T> {
  data: T;
  meta?: PaginationMeta;
  links?: PaginationLinks;
}

interface ApiError {
  error: {
    code: string;
    message: string;
    details?: FieldError[];
  };
}

// Opção B: Resposta plana (mais simples, comum para APIs internas)
// Sucesso: retorna o recurso diretamente
// Erro: retorna objeto de erro
// Distinguir pelo código de status HTTP

Paginação

Baseada em Offset (Simples)

GET /api/v1/users?page=2&per_page=20

# Implementação
SELECT * FROM users
ORDER BY created_at DESC
LIMIT 20 OFFSET 20;

Prós: Fácil de implementar, suporta "pular para página N" Contras: Lento em grandes offsets (OFFSET 100000), inconsistente com inserções concorrentes

Baseada em Cursor (Escalável)

GET /api/v1/users?cursor=eyJpZCI6MTIzfQ&limit=20

# Implementação
SELECT * FROM users
WHERE id > :cursor_id
ORDER BY id ASC
LIMIT 21;  -- busca um extra para determinar has_next
{
  "data": [...],
  "meta": {
    "has_next": true,
    "next_cursor": "eyJpZCI6MTQzfQ"
  }
}

Prós: Performance consistente independentemente da posição, estável com inserções concorrentes Contras: Não é possível pular para uma página arbitrária, cursor é opaco

Quando Usar Qual

Caso de UsoTipo de Paginação
Painéis administrativos, conjuntos pequenos (<10K)Offset
Rolagem infinita, feeds, grandes conjuntosCursor
APIs públicasCursor (padrão) com offset (opcional)
Resultados de buscaOffset (usuários esperam números de página)

Filtragem, Ordenação e Busca

Filtragem

# Igualdade simples
GET /api/v1/orders?status=active&customer_id=abc-123

# Operadores de comparação (use notação de colchetes)
GET /api/v1/products?price[gte]=10&price[lte]=100
GET /api/v1/orders?created_at[after]=2025-01-01

# Múltiplos valores (separados por vírgula)
GET /api/v1/products?category=electronics,clothing

# Campos aninhados (notação de ponto)
GET /api/v1/orders?customer.country=US

Ordenação

# Campo único (prefixo - para descendente)
GET /api/v1/products?sort=-created_at

# Múltiplos campos (separados por vírgula)
GET /api/v1/products?sort=-featured,price,-created_at

Busca de Texto Completo

# Parâmetro de consulta de busca
GET /api/v1/products?q=wireless+headphones

# Busca específica de campo
GET /api/v1/users?email=alice

Campos Esparsos

# Retorna apenas campos especificados (reduz payload)
GET /api/v1/users?fields=id,name,email
GET /api/v1/orders?fields=id,total,status&include=customer.name

Autenticação e Autorização

Autenticação Baseada em Token

# Token Bearer no cabeçalho Authorization
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

# Chave de API (para servidor a servidor)
GET /api/v1/data
X-API-Key: sk_live_abc123

Padrões de Autorização

// Nível de recurso: verificar propriedade
app.get("/api/v1/orders/:id", async (req, res) => {
  const order = await Order.findById(req.params.id);
  if (!order) return res.status(404).json({ error: { code: "not_found" } });
  if (order.userId !== req.user.id) return res.status(403).json({ error: { code: "forbidden" } });
  return res.json({ data: order });
});

// Baseado em função: verificar permissões
app.delete("/api/v1/users/:id", requireRole("admin"), async (req, res) => {
  await User.delete(req.params.id);
  return res.status(204).send();
});

Limitação de Taxa

Cabeçalhos

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000

# Quando excedido
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Limite de taxa excedido. Tente novamente em 60 segundos."
  }
}

Níveis de Limitação de Taxa

NívelLimiteJanelaCaso de Uso
Anônimo30/minPor IPEndpoints públicos
Autenticado100/minPor usuárioAcesso padrão à API
Premium1000/minPor chave de APIPlanos de API pagos
Interno10000/minPor serviçoServiço a serviço

Versionamento

Versionamento por Caminho de URL (Recomendado)

/api/v1/users
/api/v2/users

Prós: Explícito, fácil de rotear, armazenável em cache Contras: URL muda entre versões

Versionamento por Cabeçalho

GET /api/users
Accept: application/vnd.myapp.v2+json

Prós: URLs limpas Contras: Mais difícil de testar, fácil de esquecer

Estratégia de Versionamento

1. Comece com /api/v1/ — não versionar até ser necessário
2. Mantenha no máximo 2 versões ativas (atual + anterior)
3. Cronograma de descontinuação:
   - Anunciar descontinuação (aviso de 6 meses para APIs públicas)
   - Adicionar cabeçalho Sunset: Sunset: Sat, 01 Jan 2026 00:00:00 GMT
   - Retornar 410 Gone após a data de validade
4. Mudanças não disruptivas não exigem nova versão:
   - Adicionar novos campos às respostas
   - Adicionar novos parâmetros de consulta opcionais
   - Adicionar novos endpoints
5. Mudanças disruptivas exigem nova versão:
   - Remover ou renomear campos
   - Alterar tipos de campo
   - Alterar estrutura da URL
   - Alterar método de autenticação

Padrões de Implementação

TypeScript (Rota de API Next.js)

import { z } from "zod";
import { NextRequest, NextResponse } from "next/server";

const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(100),
});

export async function POST(req: NextRequest) {
  const body = await req.json();
  const parsed = createUserSchema.safeParse(body);

  if (!parsed.success) {
    return NextResponse.json({
      error: {
        code: "validation_error",
        message: "Falha na validação da requisição",
        details: parsed.error.issues.map(i => ({
          field: i.path.join("."),
          message: i.message,
          code: i.code,
        })),
      },
    }, { status: 422 });
  }

  const user = await createUser(parsed.data);

  return NextResponse.json(
    { data: user },
    {
      status: 201,
      headers: { Location: `/api/v1/users/${user.id}` },
    },
  );
}

Python (Django REST Framework)

from rest_framework import serializers, viewsets, status
from rest_framework.response import Response

class CreateUserSerializer(serializers.Serializer):
    email = serializers.EmailField()
    name = serializers.CharField(max_length=100)

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["id", "email", "name", "created_at"]

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action == "create":
            return CreateUserSerializer
        return UserSerializer

    def create(self, request):
        serializer = CreateUserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = UserService.create(**serializer.validated_data)
        return Response(
            {"data": UserSerializer(user).data},
            status=status.HTTP_201_CREATED,
            headers={"Location": f"/api/v1/users/{user.id}"},
        )

Go (net/http)

func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
    var req CreateUserRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        writeError(w, http.StatusBadRequest, "invalid_json", "Corpo da requisição inválido")
        return
    }

    if err := req.Validate(); err != nil {
        writeError(w, http.StatusUnprocessableEntity, "validation_error", err.Error())
        return
    }

    user, err := h.service.Create(r.Context(), req)
    if err != nil {
        switch {
        case errors.Is(err, domain.ErrEmailTaken):
            writeError(w, http.StatusConflict, "email_taken", "Email já registrado")
        default:
            writeError(w, http.StatusInternalServerError, "internal_error", "Erro interno")
        }
        return
    }

    w.Header().Set("Location", fmt.Sprintf("/api/v1/users/%s", user.ID))
    writeJSON(w, http.StatusCreated, map[string]any{"data": user})
}

Checklist de Design de API

Antes de lançar um novo endpoint:

  • URL do recurso segue convenções de nomenclatura (plural, kebab-case, sem verbos)
  • Método HTTP correto usado (GET para leituras, POST para criações, etc.)
  • Códigos de status apropriados retornados (não 200 para tudo)
  • Entrada validada com schema (Zod, Pydantic, Bean Validation)
  • Respostas de erro seguem formato padrão com códigos e mensagens
  • Paginação implementada para endpoints de listagem (cursor ou offset)
  • Autenticação necessária (ou explicitamente marcada como pública)
  • Autorização verificada (usuário só pode acessar seus próprios recursos)
  • Limitação de taxa configurada
  • Resposta não vaza detalhes internos (stack traces, erros SQL)
  • Nomenclatura consistente com endpoints existentes (camelCase vs snake_case)
  • Documentado (especificação OpenAPI/Swagger atualizada)

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Habilidades Relacionadas