Pular para conteúdo

Solução 03 - Modelagem REST 📡

Navegação

← Exercício 03 | Próxima Solução →

🟢 Respostas Fáceis

1. URI Design - Correção das URIs

Resposta 1

❌ URIs Incorretas✅ URIs Corretas:

| ❌ Incorreta | ✅ Correta | 📝 Explicação |
|-------------|-----------|--------------|
| `GET /listar_todos_usuarios` | `GET /usuarios` | Nomes em **português**, **verbos desnecessários** |
| `POST /criarNovoPedido` | `POST /pedidos` | **CamelCase** e verbo redundante (POST já indica criação) |
| `DELETE /remover-produto-por-id/123` | `DELETE /produtos/123` | **Hífen** e descrição longa desnecessária |

**📋 Regras REST Aplicadas:**
- **Substantivos** no plural (usuarios, pedidos, produtos)
- **Inglês** como padrão internacional
- **Verbos HTTP** indicam a ação, não a URI
- **Caminhos simples** e limpos

2. Verbos HTTP - Atualização de Senha

Resposta 2

Resposta: PATCH /usuarios/123/senha

**Justificativa:**
- **PATCH**: Atualização **parcial** de um recurso específico
- **PUT**: Substituiria **todo** o objeto usuário (overkill para só senha)
- **POST**: Usado para **criação**, não atualização

**Exemplo de payload:**
```json
{
    "senha_atual": "senha123",
    "senha_nova": "novaSenhaSegura456!"
}
```

🟡 Respostas Médias

3. Status Codes - Escolha Ideal

Resposta 3

Situações e Status Codes:

| 📋 Situação | 🎯 Status Code | 📖 Justificativa |
|-------------|----------------|------------------|
| **Usuário sem permissão de admin** para deletar | **403 Forbidden** | Acesso **negado** por falta de privilégios |
| **Cadastro realizado** e dados retornados | **201 Created** | **Recurso criado** com sucesso + localização |
| **Servidor caiu** por falta de memória | **500 Internal Server Error** | **Erro interno** não previsto pelo cliente |

**🔍 Detalhamento:**
```http
# Exemplo 403 - Sem permissão
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
    "erro": "Apenas administradores podem deletar arquivos",
    "codigo": "INSUFFICIENT_PRIVILEGES"
}

# Exemplo 201 - Criação bem-sucedida
HTTP/1.1 201 Created
Location: /usuarios/456
Content-Type: application/json
{
    "id": 456,
    "nome": "João Silva",
    "email": "joao@email.com"
}
```

4. Idempotência - POST vs GET

Resposta 4

Idempotência: Operação que pode ser repetida sem alterar o resultado.

**🔄 GET é Idempotente:**
```http
GET /usuarios/123  # 1ª chamada
GET /usuarios/123  # 2ª chamada
GET /usuarios/123  # 3ª chamada
```
**Resultado**: Sempre retorna os **mesmos dados**, sem alterações.

**❌ POST NÃO é Idempotente:**
```http
POST /usuarios     # 1ª chamada → Cria usuário ID 100
POST /usuarios     # 2ª chamada → Cria usuário ID 101
POST /usuarios     # 3ª chamada → Cria usuário ID 102
```
**Resultado**: Cada chamada **cria um novo** recurso (efeito colateral).

**🎯 Comparação Prática:**
- **GET**: Como **consultar saldo** - não muda nada
- **POST**: Como **fazer depósito** - cada um adiciona dinheiro

🔴 Resposta Desafio

5. Design de Contrato - E-commerce

Resposta 5

🛒 Design Completo das Rotas:

**a) Listar todos os itens de um carrinho específico:**
```http
GET /usuarios/123/carrinho/itens
# ou alternativa:
GET /carrinhos/456/itens
```

**b) Adicionar item ao carrinho:**
```http
POST /usuarios/123/carrinho/itens
# Payload:
{
    "produto_id": 789,
    "quantidade": 2
}
```

**c) JSON do "Item de Carrinho":**
```json
{
    "id": 1001,
    "produto_id": 789,
    "nome": "Smartphone Samsung Galaxy S24",
    "quantidade": 2,
    "preco_unitario": 2499.90,
    "subtotal": 4999.80,
    "adicionado_em": "2024-01-15T10:30:00Z"
}
```

**🗂️ Coleção Completa de Endpoints E-commerce:**
```http
# Carrinho
GET    /usuarios/{id}/carrinho              # Ver carrinho
DELETE /usuarios/{id}/carrinho              # Limpar carrinho

# Itens do Carrinho
GET    /usuarios/{id}/carrinho/itens        # Listar itens
POST   /usuarios/{id}/carrinho/itens        # Adicionar item
PUT    /usuarios/{id}/carrinho/itens/{id}   # Atualizar quantidade
DELETE /usuarios/{id}/carrinho/itens/{id}   # Remover item

# Checkout e Pedidos
POST   /usuarios/{id}/carrinho/checkout     # Finalizar compra
GET    /usuarios/{id}/pedidos               # Histórico pedidos
GET    /usuarios/{id}/pedidos/{id}          # Detalhes pedido
```

Mermaid - Fluxo Completo E-commerce

```mermaid sequenceDiagram participant C as Cliente participant API as API Gateway participant UC as User Service
participant PC as Product Service participant CC as Cart Service

    C->>+API: GET /usuarios/123/carrinho/itens
    API->>+CC: Buscar itens do carrinho
    CC->>+PC: Buscar detalhes dos produtos
    PC-->>-CC: Dados dos produtos
    CC-->>-API: Itens com detalhes
    API-->>-C: Lista de itens

    C->>+API: POST /usuarios/123/carrinho/itens
    Note over C,API: {"produto_id": 789, "quantidade": 2}
    API->>+PC: Verificar produto existe
    PC-->>-API: ✅ Produto válido
    API->>+CC: Adicionar ao carrinho
    CC-->>-API: ✅ Item adicionado
    API-->>-C: 201 Created
```

Implementação em Python (FastAPI)

```python from fastapi import FastAPI, Path from typing import List

@app.get("/usuarios/{user_id}/carrinho/itens")
async def listar_itens_carrinho(user_id: int = Path(..., gt=0)):
    return await carrinho_service.buscar_itens(user_id)

@app.post("/usuarios/{user_id}/carrinho/itens", status_code=201)
async def adicionar_item(user_id: int, item: ItemCarrinhoRequest):
    # Validar produto existe
    produto = await produto_service.buscar(item.produto_id)
    if not produto:
        raise HTTPException(404, "Produto não encontrado")

    # Adicionar ao carrinho
    item_criado = await carrinho_service.adicionar_item(
        user_id, item.produto_id, item.quantidade
    )

    return {
        "id": item_criado.id,
        "produto_id": produto.id,
        "nome": produto.nome,
        "quantidade": item.quantidade,
        "preco_unitario": produto.preco,
        "subtotal": produto.preco * item.quantidade
    }
```

!!! tip "Dicas para Próximos Estudos" - Pratique com Postman ou Insomnia testando APIs REST - Estude Richardson Maturity Model para APIs avançadas - Implemente versionamento de APIs (/v1/, /v2/) - Use OpenAPI/Swagger para documentação automática

Navegação

← Exercício 03 | Próxima Solução →