-1

I want to be able to pass function name to gin.Engine route handler. I have the following code;

// status service
type StatusService struct {
    App *gin.Engine
}

func (s *StatusService) Ping(ctx *gin.Context) {
    ctx.JSON(200, gin.H{
        "message": "pong",
    })
}

app := gin.Default()
// define services
statusService := &services.StatusService{
    App: app,
}
ss := make(map[string]interface{})
ss["auth"] = statusService

app.GET("/ping", ss["auth"].Ping)

The compiler gives the following error;

./app.go:60: ss["auth"].Ping undefined (type interface {} has no field or method Ping)

Any ideas about how to fix that?

aacanakin
  • 2,844
  • 4
  • 25
  • 42

1 Answers1

2

interface{} works for just about any type, the problem is that you've failed to assert which type the thing is. In this case you would need something like... ss["auth"].(*StatusService).Ping(myCtxInstance). This answer has a more thorough example which I'll refrain from duplicating; Go map of functions

Couple other things; if your real use case is as simple as your example just stop what you're doing and add func(ctx *gin.Context) as a second argument. Also, depending on the nature of the functions you want to use (like if they all have the same args and return types) then you might want to use a second arg for the delegates, map[string]func(argumentType) would be more appropriate.

The design you currently have pushes all errors to runtime which obviously is less desirable than the compile time safety you'd get from either of the options I touched on above.

Community
  • 1
  • 1
evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • well, I don't have to define a map struct. I may initialize a var and pass it's function to `app.GET()`. Is it more convenient to use that? – aacanakin Jun 30 '15 at 22:57
  • btw, `ss["auth"].(func(ctx *gin.Context)).Ping` doesn't work – aacanakin Jun 30 '15 at 22:59
  • @aacanakin yeah, there was one thing I didn't really notice which is that you have a recieving type of `s *StatusService` for `Ping` so you actually need do the type assert for that. I'll update that example. – evanmcdonnal Jun 30 '15 at 23:00
  • thanks. It works! `app.GET("/ping", (*statusService).Ping)` – aacanakin Jun 30 '15 at 23:03