Microsserviços em Go: arquitetura e prática para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Microsserviços em Go: da ideia à produção



Go (Golang) conquistou a reputação de ser a linguagem ideal para construir arquitetura de microsserviços. Graças ao suporte embutido para concorrência, compilação rápida, consumo mínimo de memória e sintaxe simples, o Go permite criar serviços leves e de alto desempenho. Neste artigo, vamos analisar os princípios-chave para construir microsserviços em Go, explorar exemplos práticos e melhores práticas que ajudarão você a evitar erros comuns.



Por que Go é a escolha ideal para microsserviços?



Antes de mergulharmos na arquitetura, vamos entender por que o Go se tornou o padrão de facto para microsserviços:



  • Início rápido: Go compila em um único arquivo binário, o que simplifica a implantação e o escalonamento.
  • Concorrência embutida: goroutines e channels permitem processar milhares de requisições de forma eficiente, sem threads complexas.
  • Consumo mínimo de memória: cada microsserviço em Go consome muito menos recursos do que equivalentes em Java ou Python.
  • Facilidade de manutenção: a tipagem estática e o compilador rigoroso reduzem a quantidade de erros em tempo de execução.


Arquitetura de microsserviço em Go: template básico



Vamos considerar a estrutura típica de um microsserviço em Go. Como exemplo, criaremos um serviço simples de gerenciamento de usuários.



Estrutura do projeto



user-service/├── cmd/│   └── server/│       └── main.go├── internal/│   ├── handler/│   │   └── user.go│   ├── service/│   │   └── user.go│   ├── repository/│   │   └── postgres.go│   └── model/│       └── user.go├── pkg/│   └── middleware/│       └── logging.go├── config/│   └── config.go├── go.mod└── Dockerfile


Este template segue os princípios da Clean Architecture: as dependências apontam para dentro, e a lógica de negócio é isolada da infraestrutura.



Exemplo do arquivo principal (cmd/server/main.go)



package main

import ( "log" "net/http" "os" "user-service/internal/handler" "user-service/internal/repository" "user-service/internal/service")

func main() { // Inicialização de dependências db, err := repository.NewPostgresDB("postgres://user:pass@localhost:5432/users") if err != nil { log.Fatal(err) } defer db.Close()

userRepo := repository.NewUserRepository(db) userSvc := service.NewUserService(userRepo) userHandler := handler.NewUserHandler(userSvc)

// Configuração de rotas mux := http.NewServeMux() mux.HandleFunc("GET /users/{id}", userHandler.GetByID) mux.HandleFunc("POST /users", userHandler.Create) mux.HandleFunc("PUT /users/{id}", userHandler.Update)

// Inicialização do servidor port := os.Getenv("PORT") if port == "" { port = "8080" } log.Printf("Server starting on :%s", port) log.Fatal(http.ListenAndServe(":"+port, mux))}


Implementação das camadas do microsserviço



Vamos dividir o código em três camadas principais: handler (transporte), service (lógica de negócio) e repository (acesso a dados).



Camada handler: processamento de requisições HTTP



// internal/handler/user.gopackage handler

import ( "encoding/json" "net/http" "user-service/internal/model" "user-service/internal/service")

type UserHandler struct { svc *service.UserService}

func NewUserHandler(svc *service.UserService) *UserHandler { return &UserHandler{svc: svc}}

func (h *UserHandler) GetByID(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") user, err := h.svc.GetByID(r.Context(), id) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(user)}

func (h *UserHandler) Create(w http.ResponseWriter, r *http

Blogs

Book Recommendations