Microservicios en Go: arquitectura y práctica para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Microservicios en Go: desde la idea hasta la producción



Go (Golang) se ha ganado la reputación de ser el lenguaje ideal para construir una arquitectura de microservicios. Gracias a su soporte incorporado para concurrencia, compilación rápida, consumo mínimo de memoria y sintaxis simple, Go permite crear servicios ligeros y de alto rendimiento. En este artículo, analizaremos los principios clave para construir microservicios en Go, veremos ejemplos prácticos y las mejores prácticas que te ayudarán a evitar errores típicos.



¿Por qué Go es la elección ideal para microservicios?



Antes de sumergirnos en la arquitectura, analicemos por qué Go se ha convertido en el estándar de facto para microservicios:



  • Inicio rápido: Go se compila en un único archivo binario, lo que simplifica el despliegue y la escalabilidad.
  • Concurrencia incorporada: las goroutines y los canales permiten procesar eficientemente miles de solicitudes sin hilos complejos.
  • Consumo mínimo de memoria: cada microservicio en Go consume significativamente menos recursos que sus equivalentes en Java o Python.
  • Facilidad de mantenimiento: el tipado estático y el compilador estricto reducen la cantidad de errores en tiempo de ejecución.


Arquitectura de un microservicio en Go: patrón básico



Consideremos la estructura típica de un microservicio en Go. Como ejemplo, crearemos un servicio simple de gestión de usuarios.



Estructura del proyecto



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 patrón sigue los principios de Clean Architecture: las dependencias apuntan hacia adentro y la lógica de negocio está aislada de la infraestructura.



Ejemplo del archivo 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() { // Inicialización de dependencias 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)

// Configuración de rutas mux := http.NewServeMux() mux.HandleFunc("GET /users/{id}", userHandler.GetByID) mux.HandleFunc("POST /users", userHandler.Create) mux.HandleFunc("PUT /users/{id}", userHandler.Update)

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


Implementación de las capas del microservicio



Dividamos el código en tres capas principales: handler (transporte), service (lógica de negocio) y repository (acceso a datos).



Capa handler: manejo de solicitudes 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