Knowledge

Design de APIs RESTful Modernas em 2026: Padrões e Best Practices

REST continua sendo o padrão de comunicação mais usado em 2026. Aprenda princípios de design, padrões comuns e práticas modernas para APIs RESTful de produção.

14/03/20268 min de leituraKnowledge
Design de APIs RESTful Modernas em 2026: Padrões e Best Practices

Resumo executivo

REST continua sendo o padrão de comunicação mais usado em 2026. Aprenda princípios de design, padrões comuns e práticas modernas para APIs RESTful de produção.

Ultima atualizacao: 14/03/2026

Introdução: REST continua relevante em 2026

Com GraphQL, gRPC e WebSockets ganhando popularidade, REST foi "declarado morto" diversas vezes. Em 2026, REST continua sendo o padrão de comunicação mais usado para APIs HTTP, não por nostalgia, mas por simplicidade, ferramentas maduras e cacheabilidade nativa.

APIs RESTful bem projetadas são previsíveis, documentáveis e facilmente consumíveis por qualquer cliente HTTP. O desafio não é usar HTTP — é usar HTTP de forma consistente, semântica e escalável.

Este guia cobre padrões modernos de design de APIs RESTful, princípios de arquitetura e práticas de implementação que diferenciam APIs profissionais de APIs improvisadas.

Princípios fundamentais do REST

REST vs "REST-ish"

APIs que usam HTTP e JSON não são necessariamente RESTful. REST (Representational State Transfer) é um estilo arquitetural com seis princípios:

  1. Client-server: Separação de concerns entre cliente e servidor
  2. Stateless: Cada requisição contém todas as informações necessárias
  3. Cacheable: Respostas devem definir explicitamente se podem ser cacheadas
  4. Uniform interface: Interface consistente em todos os recursos
  5. Layered system: Arquitetura pode ter camadas intermediárias (proxies, gateways)
  6. Code on demand (opcional): Servidor pode executar código no cliente (JavaScript)

APIs "REST-ish" violam esses princípios e pagam o preço em complexidade, cacheabilidade e interoperabilidade.

Interface uniforme: mais que GET, POST, PUT, DELETE

Uma API RESTful não deve restringir-se aos quatro métodos principais quando outros métodos HTTP são mais apropriados:

GET    /api/users           → Listar usuários
POST   /api/users           → Criar usuário
GET    /api/users/123       → Obter usuário específico
PUT    /api/users/123       → Substituir usuário
PATCH  /api/users/123       → Atualizar parcialmente usuário
DELETE /api/users/123       → Deletar usuário

Métodos adicionais para casos específicos:

HEAD   /api/users/123       → Obter headers sem body
OPTIONS /api/users          → Obter métodos permitidos

Patches vs PUTs:

  • PUT: Substituição completa. Envia todos os campos, mesmo os não alterados.
  • PATCH: Atualização parcial. Envia apenas os campos alterados.
json// PUT - Substituição completa
{
  "id": "123",
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30,
  "address": { "street": "123 Main St", "city": "NYC" }
}

// PATCH - Atualização parcial
{
  "age": 31
}

Design de URIs e estrutura de recursos

Nouns, not verbs

URIs devem identificar recursos, não ações:

CORRETO:
GET    /api/users
POST   /api/users
GET    /api/users/123
DELETE /api/users/123

ERRADO:
GET    /api/getUsers
POST   /api/createUser
GET    /api/getUser?id=123
POST   /api/deleteUser

Hierarquia de recursos

Use hierarquia para expressar relacionamentos:

GET    /api/users                    → Listar usuários
GET    /api/users/123               → Obter usuário
GET    /api/users/123/orders        → Pedidos do usuário
GET    /api/users/123/orders/456    → Pedido específico do usuário
POST   /api/users/123/orders        → Criar pedido para usuário

Regra de ouro: Evite URIs profundas demais. Mais de 3-4 níveis indicam que a API pode ser reorganizada.

Query strings para filtros, ordenação e paginação

Use query strings para modificar a representação, não o recurso:

GET    /api/users?age=gte:18&limit=50&offset=0&sort=-created_at

Padrões comuns de query string:

typescript// Filtros
GET /api/users?status=active
GET /api/users?status=active&role=admin

// Ordenação
GET /api/users?sort=created_at          // Crescente
GET /api/users?sort=-created_at         // Decrescente
GET /api/users?sort=created_at,name    // Múltiplos campos

// Paginação
GET /api/users?page=2&per_page=50
GET /api/users?offset=50&limit=50

// Campos (sparse fields)
GET /api/users?fields=id,name,email
GET /api/users?expand=profile,orders   // Expandir relacionamentos

// Busca
GET /api/users?q=john

Versionamento de APIs

Por que versionar?

APIs públicas são contratos. Mudanças breaking podem quebrar clientes que dependem delas. Versionar permite evoluir sem romper compatibilidade.

Estratégias de versionamento

1. URI versioning

https://api.example.com/v1/users
https://api.example.com/v2/users

Vantagens:

  • Fácil de implementar
  • Visível na URI
  • Cache friendly (cada versão é um recurso distinto)

Desvantagens:

  • URIs ficam sujas
  • Duplicação de rotas em código

2. Header versioning

GET /api/users
Accept: application/vnd.api.v1+json

Vantagens:

  • URIs limpas
  • Version negotiation via HTTP

Desvantagens:

  • Menos visível
  • Mais difícil de debugar
  • Proxy-friendly caches podem ser problema

3. Query parameter versioning

GET /api/users?v=1

Vantagens:

  • Fácil de testar
  • Não polui URI

Desvantagens:

  • Ambíguo (é parte da URI?)
  • Cache complexo

Recomendação: Use URI versioning para APIs públicas por simplicidade e cacheabilidade.

Ciclo de vida de versões

yamlv1 (Estável):
  - Bug fixes apenas
  - Suporte mínimo por 12 meses
  - Avisos de deprecation nos headers

v2 (Atual):
  - Desenvolvimento ativo
  - Mudanças breaking permitidas
  - Migration guide de v1 → v2

v3 (Beta):
  - Para early adopters
  - Pode mudar sem aviso
  - SLA não garantido

Padrões de resposta

Respostas de sucesso

json// GET /api/users/123 (200 OK)
{
  "data": {
    "id": "123",
    "name": "John Doe",
    "email": "john@example.com",
    "created_at": "2026-01-15T10:30:00Z",
    "updated_at": "2026-03-10T14:22:00Z"
  }
}

// POST /api/users (201 Created)
{
  "data": {
    "id": "124",
    "name": "Jane Smith",
    "email": "jane@example.com",
    "created_at": "2026-03-14T09:15:00Z",
    "updated_at": "2026-03-14T09:15:00Z"
  },
  "links": {
    "self": "/api/users/124"
  }
}

Headers importantes:

200 OK → Cache-Control: public, max-age=3600
201 Created → Location: /api/users/124
204 No Content → Cache-Control: no-store

Respostas de erro

Use códigos HTTP apropriados:

typescript// 400 Bad Request - Validação falhou
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      { "field": "email", "message": "Email is required" },
      { "field": "age", "message": "Age must be >= 18" }
    ]
  }
}

// 401 Unauthorized - Não autenticado
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication required"
  }
}

// 403 Forbidden - Sem permissão
{
  "error": {
    "code": "FORBIDDEN",
    "message": "You don't have permission to access this resource"
  }
}

// 404 Not Found - Recurso não existe
{
  "error": {
    "code": "NOT_FOUND",
    "message": "User with id '999' not found"
  }
}

// 409 Conflict - Conflito de estado
{
  "error": {
    "code": "EMAIL_ALREADY_EXISTS",
    "message": "Email already registered",
    "field": "email"
  }
}

// 422 Unprocessable Entity - Sintaxe correta, mas semântica inválida
{
  "error": {
    "code": "UNPROCESSABLE_ENTITY",
    "message": "Cannot delete user with active orders"
  }
}

// 429 Too Many Requests - Rate limit exceeded
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "retry_after": 60
  }
}

// 500 Internal Server Error - Erro inesperado
{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "An unexpected error occurred"
  }
}

RFC 9457: Problem Details for HTTP APIs

Padrão padronizado para respostas de erro:

json{
  "type": "https://api.example.com/problems/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "The request could not be validated",
  "instance": "/api/users",
  "errors": [
    {
      "field": "email",
      "message": "Email is required"
    }
  ]
}

Paginação

Offset-based pagination

A mais comum, mas tem problemas com performance:

GET /api/users?offset=100&limit=50
json{
  "data": [...],
  "pagination": {
    "total": 1000,
    "count": 50,
    "offset": 100,
    "limit": 50,
    "total_pages": 20,
    "current_page": 3
  },
  "links": {
    "first": "/api/users?offset=0&limit=50",
    "prev": "/api/users?offset=50&limit=50",
    "self": "/api/users?offset=100&limit=50",
    "next": "/api/users?offset=150&limit=50",
    "last": "/api/users?offset=950&limit=50"
  }
}

Problemas:

  • Offsets altos são lentos (OFFSET 100000)
  • Dados podem aparecer em duas páginas se itens forem adicionados/deletados

Cursor-based pagination

Melhor para datasets grandes e tempo-real:

GET /api/users?cursor=eyJpZCI6IDEyMywgImNyZWF0ZWRfYXQiOiAiMjAyNi0wMy0xNCJ9&limit=50
json{
  "data": [...],
  "pagination": {
    "count": 50,
    "next_cursor": "eyJpZCI6IDEyNCwgImNyZWF0ZWRfYXQiOiAiMjAyNi0wMy0xNCJ9"
  },
  "links": {
    "next": "/api/users?cursor=...&limit=50"
  }
}

Vantagens:

  • Performance consistente mesmo em offsets altos
  • Funciona bem com dados que mudam frequentemente

Desvantagens:

  • Não suporta navegação direta (pular para página específica)
  • Mais complexo de implementar

Segurança de APIs

Autenticação vs Autorização

  • Autenticação: Quem é você? (JWT, OAuth, API keys)
  • Autorização: O que você pode fazer? (Permissions, roles, scopes)

Autenticação com JWT

POST /api/auth/login
{
  "email": "user@example.com",
  "password": "password"
}

→ 200 OK
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 3600
}

Headers para requisições autenticadas:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Rate limiting

Protege contra abuso:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1678790400
json// 429 Too Many Requests
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded",
    "retry_after": 60
  }
}

CORS

Configure CORS adequadamente:

typescript// API pública (allow any origin)
app.use(cors({
  origin: '*',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

// API restrita (specific origins)
app.use(cors({
  origin: ['https://app.example.com', 'https://admin.example.com'],
  credentials: true
}));

Documentação e especificação

OpenAPI (Swagger)

Especificação aberta para APIs REST:

yamlopenapi: 3.0.0
info:
  title: User API
  version: 1.0.0
  description: API for managing users

paths:
  /users:
    get:
      summary: List users
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
    post:
      summary: Create user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUser'
      responses:
        '201':
          description: User created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        email:
          type: string
          format: email

Plano de implementação em 30 dias

Semana 1: Estrutura e consistência

  • Definir convenções de URI
  • Padronizar formato de respostas
  • Configurar estrutura de erros

Semana 2: Versionamento e documentação

  • Implementar versionamento de API
  • Criar especificação OpenAPI
  • Gerar documentação automática

Semana 3: Segurança e performance

  • Implementar autenticação JWT
  • Adicionar rate limiting
  • Configurar cache headers

Semana 4: Testes e validação

  • Criar suíte de testes de API
  • Testar versões anteriores
  • Validar conformidade com OpenAPI

Sua empresa precisa de APIs RESTful robustas, documentadas e escaláveis? Fale com especialistas da Imperialis sobre design de APIs, arquitetura de microserviços e integrações seguras.

Fontes

Leituras relacionadas