In this post we will go through how to use Uber Fx for dependency injection/singletons with Echo Web framework.
Why Are Singletons and Dependency Injection Important?
Singletons and dependency injection are very important while working with complex backend services, Singletons are important for resource efficiency, thread safety, ex. you cannot create new DB connections for every DB query etc. Dependency injection is useful for creating loosely coupled, testable and flexible code which can be easily extended.
Uber Fx is a dependency injection framework for golang build by Uber which is integrated in all the golang services in Uber to have uniform structure of code across services, code reuse is easier and makes servers efficient.
Echo is one of the most popular go webserver framework known for being high performant, extensible and minimalist.
Case Study: Order Management Service:
Suppose we have a hypothetical Order Management Service, Where have couple of endpoints to fetch user profile details, users orders, order details etc.
The service interacts with multiple databases like MogoDB, Reids, MySQL and other components like Logger, Configuration Loader, HTTP/GRPC Client Services, Other Application Modules/Services(each with its dependencies).
Challenge: These modules rely on shared resources like database connections, logger, HTTP clients etc, Managing them manually initializing, sharing, and wiring dependencies can quickly become overwhelming. Also ensuring all the dependencies are singletons across the project adds another layer of complexity.
func main(){
redisConenction := db.GetRedisconnection()
mongoConnection := db.GetMongoConnection()
orderService := services.NewOrderService(redisConenction, mongoConnection)
userService := services.NewUserService(redisConenction, mongoConnection, orderService)
// Other Services...
// Init controllers
userController := controllers.NewUserController(userService)
// Other controller...
StartEchoServer(controllers)
}
Below is the code snippet required to creating all the services with UberFx.
import (
"github.com/Ishankhan21/go-fiber-fx/controllers"
"github.com/Ishankhan21/go-fiber-fx/db"
"github.com/Ishankhan21/go-fiber-fx/services"
"go.uber.org/fx"
)
func main() {
fx.New(
fx.Provide(
db.GetRedisconnection,
db.GetMongoConnection,
services.NewUserService,
services.NewOrderService,
controllers.NewUserController),
fx.Invoke(StartEchoServer)).Run()
}
Full Code in Github
Implementation Steps:
1.Define Constructors: Create constructors for your dependencies, such as database connections, logger, and HTTP clients.
2.Integrate Uber Fx: Register these constructors with Uber Fx and let it handle initialization and injection.
3.Use Dependencies in Handlers: In your Echo handlers, Uber Fx automatically injects the required dependencies.
Wrapping Up:
By combining Uber Fx with Echo, you can build clean, maintainable, and scalable backend services. Uber Fx handles the complexity of dependency management, allowing you to focus on writing business logic rather than wiring dependencies manually.
References:
Top comments (1)
These are really good insights, got what I was looking for, thanks!