A lightweight dependency injection and handler wrapping mechanism for Gin-Gonic, simplifying the management of dependencies and enabling cleaner, more testable Gin handlers.
Note: NIG is not meant to solve complex problems. For more sophisticated dependency injection needs, consider using dedicated DI libraries like Fx or Wire.
NIG introduces three core concepts:
- Dep: Represents a dependency that can be created, set, and retrieved from the Gin context. It manages the lifecycle of dependencies within a request.
- Arg: An injectable argument for Gin handlers. It typically wraps one or more Dep instances to define the required middleware setup and value extraction from the context. Most commonly created using
FromDep()or by combining multiple dependencies. - Wrapper: Provides a fluent API for defining Gin routes, automatically injecting the specified arguments into your handlers.
go get github.com/raohwork/nigNIG follows a simple three-step pattern:
Wrap your dependencies (logger, database, etc.) as Dep instances:
var logger = nig.CreateDep("logger", func(c *gin.Context) (*zap.Logger, bool) {
// Initialize your logger with request context
return zap.NewProduction()
})
var db = nig.Use(myDBPool, "db") // Use existing connection poolCombine related dependencies into Arg instances:
// Single dependency
userArg := nig.FromDep(jwtDep)
// Multiple dependencies bundled together
type MyServices struct {
Logger
DB
}
servicesArg := nig.NewArg(func() gin.HandlersChain {
return gin.HandlersChain{loggerDep.Setup, dbDep.Setup}
}, func(c *gin.Context) MyServices {
return MyServices{ Logger: loggerDep.Get(c), DB: dbDep.Get(c) }
})Your handlers receive actual types, with dependencies visible in the function signature:
nig.With(router, servicesArg).
GET("/users", func(c *gin.Context, services MyServices) {
// services.Logger and services.DB are ready to use
})
nig.With2Args(router, servicesArg, userArg).
GET("/profile", func(c *gin.Context, services MyServices, user *User) {
// Both services and user are automatically injected
})Key Benefits:
- Dependencies are explicit in function signatures
- Type-safe dependency injection
- No magic strings or reflection at runtime
See example_test.go for a comprehensive example showing:
- Request ID extraction and logging setup
- Database dependency management
- JWT authentication with dependency chaining
- Multiple argument injection patterns
This project is licensed under the Mozilla Public License 2.0. See the license header in source files for details.