🧩 Exercícios: Clean Architecture em Go: Handlers, Services e Repositories
Spec Backend Com Golang E Gin • Trilha Progressiva em 4 Níveis
🎯 Nível 1: Fundamentos
Problema 09.1 — Definição de Interfaces de Domínio e Repository Pattern
Contexto: Definição de Interfaces de Domínio e Repository Pattern no contexto de Clean Architecture em Go: Handlers, Services e Repositories.
Requisitos de Execução:
- Declarar interface
ProdutoRepositorycom métodosBuscarPorID,SalvareListar.
Resultado Esperado
Contratos de repositório declarados com interfaces Go desacopladas.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_09_1_SeuNome - Envie na tarefa:
Atividade Cap 09 - Clean Architecture em Go: Handlers, Services e Repositories
🔑 Gabarito de Código & Solução Comentada
// domain/repository.go
package domain
type Produto struct {
ID uint
Nome string
Preco float64
}
type ProdutoRepository interface {
BuscarPorID(id uint) (*Produto, error)
Salvar(p *Produto) error
Listar() ([]Produto, error)
}
🔍 Nível 2: Prática
Problema 09.2 — Camada de Service (Casos de Uso) com Regras de Negócio
Contexto: Camada de Service (Casos de Uso) com Regras de Negócio no contexto de Clean Architecture em Go: Handlers, Services e Repositories.
Requisitos de Execução:
- Implementar
ProdutoServicerecebendo o repositório por injeção e aplicando regra de desconto corporativo.
Resultado Esperado
Service calculou regra de negócio e delegou persistência ao repositório.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_09_2_SeuNome - Envie na tarefa:
Atividade Cap 09 - Clean Architecture em Go: Handlers, Services e Repositories
🔑 Gabarito de Código & Solução Comentada
// usecase/produto_service.go
package usecase
import (
"errors"
"espec_backend_go_gin/domain"
)
type ProdutoService struct {
repo domain.ProdutoRepository
}
func NewProdutoService(repo domain.ProdutoRepository) *ProdutoService {
return &ProdutoService{repo: repo}
}
func (s *ProdutoService) AplicarDesconto(id uint, pct float64) (*domain.Produto, error) {
if pct <= 0 || pct > 50 { return nil, errors.New("desconto inválido") }
p, err := s.repo.BuscarPorID(id)
if err != nil { return nil, err }
p.Preco -= p.Preco * (pct / 100)
if err := s.repo.Salvar(p); err != nil { return nil, err }
return p, nil
}
⚡ Nível 3: Integração
Problema 09.3 — Handler Gin Consumindo a Camada de Serviço
Contexto: Handler Gin Consumindo a Camada de Serviço no contexto de Clean Architecture em Go: Handlers, Services e Repositories.
Requisitos de Execução:
- Criar handler HTTP que receba DTO, chame o Service e formate resposta JSON.
Resultado Esperado
Handler HTTP desacoplado da lógica de persistência e regras de negócio.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_09_3_SeuNome - Envie na tarefa:
Atividade Cap 09 - Clean Architecture em Go: Handlers, Services e Repositories
🔑 Gabarito de Código & Solução Comentada
// http/handler.go
package http
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"espec_backend_go_gin/usecase"
)
type ProdutoHandler struct {
service *usecase.ProdutoService
}
func NewProdutoHandler(s *usecase.ProdutoService) *ProdutoHandler {
return &ProdutoHandler{service: s}
}
func (h *ProdutoHandler) AplicarDesconto(c *gin.Context) {
idStr := c.Param("id")
id, _ := strconv.Atoi(idStr)
prod, err := h.service.AplicarDesconto(uint(id), 10.0)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"erro": err.Error()})
return
}
c.JSON(http.StatusOK, prod)
}
🏆 Nível 4: Desafio Corporativo
Problema 09.4 — Injeção de Dependências e Wire/DI Container
Contexto: Injeção de Dependências e Wire/DI Container no contexto de Clean Architecture em Go: Handlers, Services e Repositories.
Requisitos de Execução:
- Montar composição raiz (
main.go) instanciando Repository -> Service -> Handler sem acoplamento direto.
Resultado Esperado
Clean Architecture montada com sucesso: Handlers -> Services -> Repositories.
📤 Instruções de Entrega (Microsoft Teams)
- Salve o arquivo como:
Atividade_09_4_SeuNome - Envie na tarefa:
Atividade Cap 09 - Clean Architecture em Go: Handlers, Services e Repositories
🔑 Gabarito de Código & Solução Comentada
// wire_setup.go
package main
import (
"espec_backend_go_gin/http"
"espec_backend_go_gin/usecase"
)
type MemoryRepo struct{}
func (m *MemoryRepo) BuscarPorID(id uint) (*domain.Produto, error) { return &domain.Produto{ID: id, Nome: "Teclado", Preco: 100.0}, nil }
func (m *MemoryRepo) Salvar(p *domain.Produto) error { return nil }
func (m *MemoryRepo) Listar() ([]domain.Produto, error) { return nil, nil }
func SetupApp() *http.ProdutoHandler {
repo := &MemoryRepo{}
svc := usecase.NewProdutoService(repo)
return http.NewProdutoHandler(svc)
}