Reputation: 3245
I'm trying to pass a logger reference initialised inside main.go to Controller layer via the router like bellow
main.go
logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
routers.Init(sugar)
routers.go
func Init(l *zap.SugaredLogger) {
nsMgt := beego.NewNamespace("/api",
beego.NSNamespace("/account",
beego.NSInclude(
&controllers.AccountController{
Logger: l,
},
),
),
)
)
controller.go
type AccountController struct {
beego.Controller
Logger *zap.SugaredLogger
}
// @Title Get account details.
// @Summary Get account details
// @Param filterKey query string true "possible values 'id' or 'username'"
// @Param filterValue query string true "value of the filter key"
// @Success 200 {object} models.User
// @router / [get]
func (o *AccountController) Get() {
o.Logger.Info("this is cool")
}
It throws a null pointer error at the controller function. Is there a way to pass a global logger variable to controller layer?. It's important to initialise the logger at the main function 'cause it requires a defered close.
Upvotes: 2
Views: 1415
Reputation: 605
Beego uses reflection to create a controller instance for each request, it doesn't use the actual instance you pass in and it doesn't passes the params to the new instances. You can define "Prepare" method on your controller which will be called by Beego in runtime before invoking the matched controller method, there you can initialize the required struct fields (e.g. service layer) by calling a factory method or some sort of IoC container (Not sure if this is the best practice for Go)
I also looked for an option to pass dependencies when initializing the struct but it's not possible at the moment.
Take a look on the request handling logic: https://beego.me/docs/mvc/
Prepare method is documented here: https://beego.me/docs/mvc/controller/controller.md
Upvotes: 1