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.
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:
- Client-server: Separação de concerns entre cliente e servidor
- Stateless: Cada requisição contém todas as informações necessárias
- Cacheable: Respostas devem definir explicitamente se podem ser cacheadas
- Uniform interface: Interface consistente em todos os recursos
- Layered system: Arquitetura pode ter camadas intermediárias (proxies, gateways)
- 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árioMétodos adicionais para casos específicos:
HEAD /api/users/123 → Obter headers sem body
OPTIONS /api/users → Obter métodos permitidosPatches 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/deleteUserHierarquia 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árioRegra 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_atPadrõ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=johnVersionamento 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/usersVantagens:
- 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+jsonVantagens:
- 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=1Vantagens:
- 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 garantidoPadrõ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-storeRespostas 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=50json{
"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=50json{
"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: 1678790400json// 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: emailPlano 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.