Go dependency injection with Uber Fx and Echo

ishankhan21

Ishan Khan

Posted on November 23, 2024

Go dependency injection with Uber Fx and Echo

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.

Dependencies structure
Manual initialisations:

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)
}
Enter fullscreen mode Exit fullscreen mode

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()
}
Enter fullscreen mode Exit fullscreen mode

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:

💖 💪 🙅 🚩
ishankhan21
Ishan Khan

Posted on November 23, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related