A adoção de uma arquitetura bem definida é essencial para o desenvolvimento de aplicações robustas e escaláveis. Em Go, o padrão MVC (Model-View-Cotnroller) pode ser implementado de forma eficiente utilizando o framework web Gin para o roteamento e o GORM como ferramenta de ORM (Object-Relational Mapping) para interação com bancos de dados relacionais.
Para iniciar o projeto, é necessário instalar as dependências fundamentais via terminal:
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
A organização sugerida para este projeto separa as responsabilidades em camadas distintas, facilitando a manutenção e os testes unitários:
- main.go
- controllers/
- usuario_controller.go
- models/
- usuario.go
- services/
- usuario_service.go
- repositories/
- usuario_repository.go
1. Definição do Modelo
No diretório models/usuario.go, definimos a estrutura de dados que representa a tabela no banco de dados.
package models
type Usuario struct {
ID uint `gorm:"primaryKey;column:id" json:"id"`
Nome string `gorm:"column:nome_usuario" json:"nome"`
Email string `gorm:"column:email" json:"email"`
Endereco string `gorm:"column:endereco" json:"endereco"`
}
2. Camada de Repositório
A camada de repositório isola o acesso aos dados. Em repositories/usuario_repository.go, implementamos as opperações de consulta utilizando o GORM.
package repositories
import (
"projeto_mvc/models"
"gorm.io/gorm"
)
type UsuarioRepo struct {
db *gorm.DB
}
func NovoUsuarioRepo(db *gorm.DB) *UsuarioRepo {
return &UsuarioRepo{db: db}
}
func (r *UsuarioRepo) BuscarTodos() ([]models.Usuario, error) {
var usuarios []models.Usuario
if err := r.db.Find(&usuarios).Error; err != nil {
return nil, err
}
return usuarios, nil
}
3. Camada de Serviço
A camada de serviço em services/usuario_service.go contém a lógica de negócio e atua como ponte entre o controlador e o repositório.
package services
import (
"projeto_mvc/models"
"projeto_mvc/repositories"
)
type UsuarioService struct {
repo *repositories.UsuarioRepo
}
func NovoUsuarioService(r *repositories.UsuarioRepo) *UsuarioService {
return &UsuarioService{repo: r}
}
func (s *UsuarioService) ListarUsuarios() ([]models.Usuario, error) {
// Aqui poderiam ser adicionadas regras de negócio adicionais
return s.repo.BuscarTodos()
}
4. Camada de Controle
O controlador em controllers/usuario_controller.go gerencia as requisições HTTP, processa a entrada e retorna a resposta formatada ao cliente.
package controllers
import (
"net/http"
"projeto_mvc/services"
"github.com/gin-gonic/gin"
)
type UsuarioHandler struct {
service *services.UsuarioService
}
func NovoUsuarioHandler(s *services.UsuarioService) *UsuarioHandler {
return &UsuarioHandler{service: s}
}
func (h *UsuarioHandler) ListarTodos(c *gin.Context) {
resultado, err := h.service.ListarUsuarios()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"erro": "Falha ao recuperar dados"})
return
}
c.JSON(http.StatusOK, resultado)
}
5. Ponto de Entrada (Main)
O arquivo main.go é responsável por configurar a conexão com o banco de dados, instanciar as dependências e definir as rotas da API.
package main
import (
"log"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"projeto_mvc/controllers"
"projeto_mvc/repositories"
"projeto_mvc/services"
)
func configurarDB() *gorm.DB {
dsn := "usuario:senha@tcp(127.0.0.1:3306)/nome_banco?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("Erro ao conectar no banco de dados:", err)
}
return db
}
func main() {
router := gin.Default()
database := configurarDB()
// Injeção de dependências
repo := repositories.NovoUsuarioRepo(database)
svc := services.NovoUsuarioService(repo)
handler := controllers.NovoUsuarioHandler(svc)
// Definição de rotas
v1 := router.Group("/api/v1")
{
v1.GET("/usuarios", handler.ListarTodos)
}
router.Run(":8080")
}
Ao estruturar a aplicação desta forma, garantimos que cada componente tenha uma responsabilidade única (Single Responsibility Principle). O repositório lida exclusivamente com o banco de dados, o serviço com as regras de negócio e o controlador com a interface de comunicação HTTP, resultando em um código mais limpo e modular.