Introdução: Por que Go é a linguagem ideal para microsserviços?
\n\nA arquitetura de microsserviços tornou-se o padrão de facto para a construção de aplicações modernas e escaláveis. A linguagem Go (Golang), criada nos laboratórios do Google, é ideal para esta tarefa devido à sua simplicidade, desempenho e suporte nativo à concorrência. Neste artigo, abordaremos o ciclo completo de criação de um microsserviço em Go: desde o design da arquitetura até a implantação em produção.
\n\nGo oferece compilação rápida, consumo mínimo de memória e trabalho nativo com goroutines — threads leves. Isso o torna uma excelente escolha para sistemas distribuídos de alta carga. Exploraremos conceitos-chave, escreveremos exemplos de código e discutiremos as melhores práticas.
\n\n1. Design da arquitetura de microsserviços em Go
\n\n1.1. Princípios da arquitetura de microsserviços
\n\nAntes de escrever código, é necessário definir os limites dos microsserviços. Os princípios básicos são:
\n\n- \n
- Responsabilidade Única (Single Responsibility) — cada serviço é responsável por uma função de negócio. \n
- Independência de implantação — cada microsserviço pode ser atualizado sem parar todo o sistema. \n
- Baixo Acoplamento (Loose Coupling) — os serviços se comunicam através de APIs bem definidas. \n
- Descentralização do gerenciamento de dados — cada serviço possui seu próprio banco de dados. \n
1.2. Estrutura do projeto Go para microsserviço
\n\nEstrutura de pastas recomendada para um microsserviço em Go:
\n\nmy-service/\n├── cmd/\n│ └── server/\n│ └── main.go # Ponto de entrada\n├── internal/\n│ ├── handler/ # Manipuladores HTTP/gRPC\n│ ├── service/ # Lógica de negócios\n│ ├── repository/ # Trabalho com BD\n│ └── model/ # Estruturas de dados\n├── pkg/\n│ └── api/ # Arquivos proto comuns (gRPC)\n├── config/\n│ └── config.go # Configuração\n├── migrations/ # Migrações do BD\n├── Dockerfile\n└── go.mod\n\n1.3. Exemplo de um microsserviço simples
\n\nVamos criar um microsserviço HTTP básico para gerenciamento de usuários. Começaremos definindo o modelo e o repositório:
\n\n// internal/model/user.go\npackage model\n\ntype User struct {\n ID int64 `json:"id"`\n Name string `json:"name"`\n Email string `json:"email"`\n}\n\n// internal/repository/user_repo.go\npackage repository\n\nimport (\n "context"\n "my-service/internal/model"\n)\n\ntype UserRepository interface {\n GetByID(ctx context.Context, id int64) (*model.User, error)\n Create(ctx context.Context, user *model.User) (int64, error)\n}\n\ntype inMemoryRepo struct {\n users map[int64]*model.User\n nextID int64\n}\n\nfunc NewInMemoryRepo() UserRepository {\n return &inMemoryRepo{\n users: make(map[int64]*model.User),\n nextID: 1,\n }\n}\n\nfunc (r *inMemoryRepo) GetByID(ctx context.Context, id int64) (*model.User, error) {\n user, ok := r.users[id]\n if !ok {\n return nil, fmt.Errorf("user not found")\n }\n return user, nil\n}\n\nfunc (r *inMemoryRepo) Create(ctx context.Context, user *model.User) (int64, error) {\n user.ID = r.nextID\n r.users[user.ID] = user\n r.nextID++\n return user.ID, nil\n}\n\n2. Comunicação entre microsserviços: REST, gRPC e filas
\n\n2.1. REST API em Go
\n\nPara interação síncrona, os mais utilizados são REST ou gRPC. Vamos considerar um controlador REST usando a biblioteca padrão net/http e o roteador chi:
// internal/handler/user_handler.go\npackage handler\n\nimport (\n "encoding/json"\n "net/http"\n "strconv"\n "my-service/internal/service"\n "github.com/go-chi/chi/v5"\n)\n\ntype UserHandler struct {\n svc *service.UserService\n}\n\nfunc NewUserHandler(svc *service.UserService) *UserHandler {\n