¿Qué es esta librería y para qué sirve?
fx es un potente framework de inyección de dependencias (DI) para el lenguaje Go, desarrollado por Uber. Proporciona una forma elegante de gestionar las dependencias en aplicaciones Go, automatizando la creación, vinculación y el ciclo de vida de los objetos.
En una aplicación Go tradicional, los desarrolladores suelen enfrentarse al problema del "infierno de constructores" (constructor hell), donde para crear un objeto se deben pasar múltiples dependencias. Esto conlleva:
- Código verboso con gestión manual de dependencias
- Dificultades al realizar pruebas
- Problemas al modificar la arquitectura de la aplicación
fx resuelve estos problemas ofreciendo:
- Inyección automática de dependencias — el framework determina qué objetos se necesitan y en qué orden crearlos
- Gestión del ciclo de vida — inicio y detención automática de componentes
- Modularidad — la aplicación se divide en módulos independientes
- Facilidad de prueba — permite reemplazar dependencias reales con objetos mock fácilmente
fx es especialmente útil en el desarrollo de:
- Microservicios
- Aplicaciones web
- Herramientas CLI
- Cualquier aplicación con una arquitectura compleja de dependencias
Instalación
La instalación de fx se realiza de forma estándar para librerías Go mediante go get:
go get go.uber.org/fx
Para actualizar a la última versión:
go get -u go.uber.org/fx
Después de la instalación, importa la librería en tu código:
import "go.uber.org/fx"
También se recomienda instalar la utilidad fx para generación de código (opcional):
go install go.uber.org/fx/cmd/fx@latest
Inicio rápido con ejemplo de código
Veamos un ejemplo sencillo de uso de fx para crear un servidor HTTP:
package main
import (
"context"
"fmt"
"net/http"
"go.uber.org/fx"
)
// NewHandler crea un manejador HTTP
func NewHandler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "¡Hola, fx!")
})
return mux
}
// NewServer crea un servidor HTTP
func NewServer(handler http.Handler) *http.Server {
return &http.Server{
Addr: ":8080",
Handler: handler,
}
}
// StartServer inicia el servidor
func StartServer(lc fx.Lifecycle, server *http.Server) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
go server.ListenAndServe()
fmt.Println("Servidor iniciado en :8080")
return nil
},
OnStop: func(ctx context.Context) error {
return server.Shutdown(ctx)
},
})
}
func main() {
app := fx.New(
fx.Provide(NewHandler),
fx.Provide(NewServer),
fx.Invoke(StartServer),
)
app.Run()
}
Este ejemplo muestra la mecánica básica de fx:
- fx.Provide — registra los constructores
- fx.Invoke — ejecuta funciones que utilizan las dependencias
- fx.Lifecycle — gestiona el ciclo de vida de los componentes
Métodos/funciones principales
1. fx.New
Qué hace: Crea una nueva aplicación fx que gestiona las dependencias. Es el punto de entrada principal del framework.
Parámetros:
- options ...Option — función variádica que acepta uno o más parámetros de tipo Option (fx.Provide, fx.Invoke, fx.Module, etc.)
Ejemplo de código funcional:
package main
import (
"go.uber.org/fx"
)
type Config struct {
Port int
}
func NewConfig() *Config {
retur