O que é esta biblioteca e para que serve
fx é um poderoso framework de dependency injection (DI) para a linguagem Go, desenvolvido pela Uber. Ele oferece uma maneira elegante de gerenciar dependências em aplicações Go, automatizando a criação, vinculação e o ciclo de vida dos objetos.
Em uma aplicação Go tradicional, os desenvolvedores frequentemente enfrentam o problema do "inferno dos construtores" (constructor hell), onde para criar um objeto é necessário passar várias dependências. Isso resulta em:
- Código extenso com gerenciamento manual de dependências
- Dificuldades na hora de testar
- Problemas ao modificar a arquitetura da aplicação
O fx resolve esses problemas oferecendo:
- Injeção automática de dependências — o framework determina quais objetos são necessários e em qual ordem criá-los
- Gerenciamento do ciclo de vida — inicialização e parada automática dos componentes
- Modularidade — a aplicação é dividida em módulos independentes
- Facilidade de teste — substitua dependências reais por mocks de forma simples
O fx é especialmente útil no desenvolvimento de:
- Microsserviços
- Aplicações web
- Ferramentas CLI
- Qualquer aplicação com arquitetura complexa de dependências
Instalação
A instalação do fx é feita da forma padrão para bibliotecas Go, usando o comando go get:
go get go.uber.org/fx
Para atualizar para a versão mais recente:
go get -u go.uber.org/fx
Após a instalação, importe a biblioteca no seu código:
import "go.uber.org/fx"
Também é recomendável instalar a ferramenta fx para geração de código (opcional):
go install go.uber.org/fx/cmd/fx@latest
Início rápido com exemplo de código
Vamos ver um exemplo simples de uso do fx para criar um servidor HTTP:
package main
import (
"context"
"fmt"
"net/http"
"go.uber.org/fx"
)
// NewHandler cria um manipulador HTTP
func NewHandler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Olá, fx!")
})
return mux
}
// NewServer cria um servidor HTTP
func NewServer(handler http.Handler) *http.Server {
return &http.Server{
Addr: ":8080",
Handler: handler,
}
}
// StartServer inicia o 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 na porta :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 exemplo demonstra a mecânica básica do fx:
- fx.Provide — registra os construtores
- fx.Invoke — executa funções que utilizam as dependências
- fx.Lifecycle — gerencia o ciclo de vida dos componentes
Principais métodos/funções
1. fx.New
O que faz: Cria uma nova aplicação fx que gerencia as dependências. Este é o ponto de entrada principal do framework.
Parâmetros:
- options ...Option — função variádica que aceita um ou mais parâmetros do tipo Option (fx.Provide, fx.Invoke, fx.Module, etc.)
Exemplo prático de código:
package main
import (
"go.uber.org/fx"
)
type Config struct {
Port int
}
func NewConfig() *Config {
retur