Receber por email
← Voltar para o catálogo

api-design

Use this skill when designing APIs, choosing between REST/GraphQL/gRPC, writing OpenAPI specs, implementing pagination, versioning endpoints, or structuring request/response schemas. Triggers on API design, endpoint naming, HTTP methods, status codes, rate limiting, authentication schemes, HATEOAS, query parameters, and any task requiring API architecture decisions.

185estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add AbsolutelySkilled/AbsolutelySkilled

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/api-design-absolutelyskilled/svg)](https://www.skillteca.com.br/skills/api-design-absolutelyskilled)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

When this skill is activated, always start your first response with the 🧢 emoji.

API Design

API design is the practice of defining the contract between a service and its consumers in a way that is consistent, predictable, and resilient to change. A well-designed API reduces integration friction, makes versioning safe, and communicates intent through naming and structure rather than documentation alone. This skill covers the three dominant paradigms - REST, GraphQL, and gRPC - along with OpenAPI specs, pagination strategies, versioning, error formats, and authentication patterns.

When to use this skill

Trigger this skill when the user:

  • Asks how to name, structure, or version API endpoints
  • Needs to choose between REST, GraphQL, or gRPC for a new service
  • Wants to write or review an OpenAPI / Swagger specification
  • Asks about HTTP status codes and when to use each
  • Needs to implement pagination (offset, cursor, keyset)
  • Asks about authentication schemes (API key, OAuth2, JWT)
  • Wants a consistent error response format across their API
  • Needs to design request/response schemas or query parameters

Do NOT trigger this skill for:

  • Internal function/method interfaces inside a single service - use clean-code or clean-architecture skills
  • Database schema design unless it is driven by API contract requirements

Key principles

  1. Consistency over cleverness - Every endpoint, field name, error shape, and

status code should follow the same pattern throughout the API. Consumers should be able to predict behavior for an endpoint they have never used before.

  1. Resource-oriented design - Model your API around nouns (resources), not

verbs (actions). POST /orders is better than POST /createOrder. The HTTP method carries the verb.

  1. Proper HTTP semantics - Use the right method (GET is safe + idempotent,

PUT/DELETE are idempotent, POST is neither). Use correct status codes: 201 for creation, 204 for empty success, 400 for client errors, 404 for not found, 409 for conflicts, 429 for rate limiting.

  1. Version from day one - Include a version in your URL or header before

publishing. v1 in the path costs nothing; removing a breaking change from a production API costs everything.

  1. Design for the consumer - Shape responses around what the client needs, not

around what the database returns. Clients should not have to join, filter, or transform data after receiving a response.

Core concepts

REST resources

REST treats everything as a resource identified by a URL. Resources are manipulated through a uniform interface: GET, POST, PUT, PATCH, DELETE. Collections live at /resources and individual items at /resources/{id}. Sub-resources express ownership: /users/{id}/orders.

GraphQL schema

GraphQL exposes a single endpoint and lets clients declare exactly which fields they need. The schema is the contract - it defines types, queries, mutations, and subscriptions. Best for: UIs that need flexible data fetching, aggregating multiple back-end services, or reducing over/under-fetching.

gRPC + Protobuf

gRPC uses Protocol Buffers as its IDL and HTTP/2 as transport. It generates strongly-typed client/server stubs. Best for: internal service-to-service communication where performance, type safety, and streaming matter more than browser compatibility.

When to use which

| Need | REST | GraphQL | gRPC | |------|------|---------|------| | Public/partner API | Best | Good | Avoid | | Browser clients | Best | Best | Poor | | Internal microservices | Good | Overkill | Best | | Real-time / streaming | Polling/SSE | Subscriptions | Best | | Flexible field selection | Sparse fieldsets | Best | N/A | | Type-safe contracts | OpenAPI | Schema | Proto |

Common tasks

1. Design RESTful resource endpoints

Use lowercase, hyphen-separated plural nouns. Never use verbs in the path.

# Collections
GET    /v1/articles          - list
POST   /v1/articles          - create

# Single resource
GET    /v1/articles/{id}     - read
PUT    /v1/articles/{id}     - full replace
PATCH  /v1/articles/{id}     - partial update
DELETE /v1/articles/{id}     - delete

# Sub-resources
GET    /v1/users/{id}/orders - list orders for a user

# Actions that don't map to CRUD (use verb noun under resource)
POST   /v1/orders/{id}/cancel
POST   /v1/users/{id}/password-reset

2. Write an OpenAPI 3.1 spec

Always use $ref to pull components out of paths for reuse. See references/openapi-patterns.md for the full component library (security schemes, reusable responses, discriminators, webhooks).

openapi: 3.1.0
info:
  title: Articles API
  version: 1.0.0

servers:
  - url: https://api.example.com/v1

paths:
  /articles:
    get:
      operationId: listArticles
      summary: List articles
      tags: [Articles]
      parameters:
        - { name: cursor, in: query, schema: { type: string } }
        - { name: limit,  in: query, schema: { type: integer, default: 20, maximum: 100 } }
      responses:
        '200':
          description: Paginated list of articles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArticleListResponse'
        '400': { $ref: '#/components/responses/BadRequest' }

    post:
      operationId: createArticle
      summary: Create an article
      tags: [Articles]
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title: { type: string, maxLength: 255 }
                body:  { type: string }
      responses:
        '201':
          description: Article created
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Article' }
        '422': { $ref: '#/components/responses/UnprocessableEntity' }

components:
  schemas:
    Article:
      type: object
      required: [id, title, status, createdAt]
      properties:
        id:        { type: string, format: uuid }
        title:     { type: string, maxLength: 255 }
        status:    { type: string, enum: [draft, published, archived] }
        createdAt: { type: string, format: date-time }

    ArticleListResponse:
      type: object
      required: [data, pagination]
      properties:
        data:
          type: array
          items: { $ref: '#/components/schemas/Article' }
        pagination:
          type: object
          properties:
            nextCursor: { type: [string, "null"] }
            hasMore:    { type: boolean }

  responses:
    BadRequest:
      description: Invalid request
      content:
        application/problem+json:
          schema: { $ref: '#/components/schemas/ProblemDetails' }
    UnprocessableEntity:
      description: Validation failed
      content:
        application/problem+json:
          schema: { $ref: '#/components/schemas/ProblemDetails' }

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

3. Implement cursor-based pagination

Cursor pagination is stable under concurrent writes; offset pagination is not.

interface PaginationParams {
  cursor?: string;
  limit?: number;
}

interface PaginatedResult<T> {
  data: T[];
  pagination: {
    nextCursor: string | null;
    hasMore: boolean;
  };
}

async function listArticles(
  params: PaginationParams
): Promise<PaginatedResult<Article>> {
  const limit = Math.min(params.limit ?? 20, 100);

  // Decode opaque cursor back to an internal value
  const afterId = params.cursor
    ? Buffer.from(params.cursor, 'base64url').toString('utf8')
    : null;

  const rows = await db.article.findMany({
    where: afterId ? { id: { gt: afterId } } : undefined,
    orderBy: { id: 'asc' },
    take: limit + 1, // f
Compartilhar X LinkedIn