Boas práticas de nomenclatura de rotas e recursos em APIs REST

1. Fundamentos da nomenclatura RESTful

APIs REST bem projetadas baseiam-se em uma nomenclatura consistente e previsível. O princípio fundamental é tratar cada endpoint como um recurso, representado por substantivos no plural. A hierarquia é expressa com barras (/), e os verbos HTTP (GET, POST, PUT, DELETE) definem as operações, eliminando a necessidade de verbos nos nomes das rotas.

Exemplo correto:

GET    /clientes          # Listar clientes
POST   /clientes          # Criar cliente
GET    /clientes/{id}     # Obter cliente específico
PUT    /clientes/{id}     # Atualizar cliente
DELETE /clientes/{id}     # Remover cliente

Exemplo incorreto (com verbos):

GET /obterClientes
POST /criarCliente
PUT /atualizarCliente
DELETE /deletarCliente

A consistência entre nomes de recursos e operações HTTP é essencial: cada recurso deve ter um conjunto previsível de endpoints. Se você define /clientes para GET e POST, naturalmente espera-se que /clientes/{id} suporte GET, PUT e DELETE.

2. Regras para nomes de recursos

Evite verbos e ações nos endpoints. O verbo HTTP já indica a ação. Prefira:

POST /pedidos              # Em vez de /criarPedido
DELETE /pedidos/{id}       # Em vez de /removerPedido

Use letras minúsculas e hífens para separar palavras. Hífens são mais legíveis que underscores ou camelCase em URLs:

/ordens-de-compra          # Correto (hífens)
/ordens_de_compra          # Evitar (underscores)
/ordensDeCompra            # Evitar (camelCase)

Evite caracteres especiais como espaços, acentos ou símbolos. URLs devem ser seguras para transmissão HTTP:

/produtos/notebook-gamer  # Correto
/produtos/notebook gamer  # Incorreto (espaço)

3. Estrutura de rotas aninhadas e relacionamentos

Relacionamentos entre recursos são representados com sub-recursos. A hierarquia reflete a estrutura de dados:

GET /clientes/{id}/pedidos              # Pedidos de um cliente
GET /clientes/{id}/pedidos/{pedidoId}   # Pedido específico de um cliente

Limite a profundidade de aninhamento a no máximo 2-3 níveis. Aninhamentos profundos tornam a API confusa:

# Aceitável (2 níveis)
/clientes/{id}/pedidos/{pedidoId}/itens

# Evitar (muitos níveis)
/clientes/{id}/pedidos/{pedidoId}/itens/{itemId}/fornecedores

Use parâmetros de consulta (query strings) para filtros, em vez de criar sub-rotas desnecessárias:

# Melhor prática: usar query string
GET /pedidos?status=entregue&cliente_id=123

# Evitar: sub-rota desnecessária
GET /pedidos/status/entregue/cliente/123

4. Versionamento e identificação de recursos

Estratégias de versionamento mais comuns:

  • Prefixo na URL (recomendado para simplicidade): /v1/usuarios, /v2/usuarios
  • Cabeçalho Accept: Accept: application/vnd.api.v1+json (mais flexível, mas complexo)

Identificação única de recursos com IDs. Prefira UUIDs a IDs sequenciais para evitar exposição de informações:

GET /produtos/550e8400-e29b-41d4-a716-446655440000  # UUID
GET /produtos/123                                     # Sequencial (evitar)

Slugs amigáveis podem complementar IDs para rotas públicas:

GET /produtos/notebook-gamer-2024    # Slug legível
GET /produtos/{id}                   # ID para operações internas

5. Tratamento de coleções, filtros e paginação

Padronize parâmetros de paginação com nomes consistentes:

GET /clientes?page=2&limit=20&offset=40

Filtros com nomes descritivos e mesma estrutura em toda a API:

GET /pedidos?status=ativo&categoria=livros&data_inicio=2024-01-01

Use sort, fields e embed para ordenação, projeção e inclusão de relacionamentos:

GET /clientes?sort=nome,-data_criacao&fields=nome,email&embed=pedidos
  • sort=nome ordena ascendente; -data_criacao ordena descendente
  • fields=nome,email retorna apenas esses campos
  • embed=pedidos inclui relacionamentos na resposta

6. Rotas para ações não-CRUD e operações especiais

Ações customizadas devem ser representadas como sub-recursos, usando POST para alterações de estado:

POST /usuarios/{id}/ativar          # Ativar usuário
POST /pedidos/{id}/cancelar         # Cancelar pedido
POST /contas/{id}/bloquear          # Bloquear conta

Use verbos HTTP adequados:

  • GET: apenas para consultas que não alteram estado
  • POST: para criar recursos ou executar ações que alteram estado
  • PUT: para substituição completa de recurso
  • PATCH: para atualização parcial
  • DELETE: para remoção

Evite misturar ações em GET que alteram estado:

# Incorreto: GET alterando estado
GET /usuarios/123/ativar

# Correto: POST para ação que altera estado
POST /usuarios/123/ativar

7. Consistência e documentação da API

Padronize respostas de erro com códigos HTTP e mensagens descritivas:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "erro": "Dados inválidos",
  "detalhes": [
    { "campo": "email", "mensagem": "Formato de email inválido" }
  ],
  "codigo": "VALIDATION_ERROR"
}

Documente as convenções de nomenclatura para toda a equipe, incluindo:

  • Uso de substantivos no plural
  • Hífens para separar palavras
  • Estrutura de aninhamento máxima
  • Padrão de parâmetros de consulta

Use OpenAPI/Swagger para validar e comunicar a estrutura de rotas. Um arquivo OpenAPI bem escrito serve como contrato oficial da API:

openapi: 3.0.0
info:
  title: API de E-commerce
  version: v1
paths:
  /clientes:
    get:
      summary: Lista todos os clientes
      parameters:
        - name: page
          in: query
          schema:
            type: integer

Referências