2016-10-31 1 views
0

Ich versuche, Validator/Binder-Middleware in Go mit Gin-Framework zu erstellen.Erstellen einer Variablen des Typs von der Schnittstelle in Golang

Dies ist das Modell

type LoginForm struct{ 
    Email string `json:"email" form:"email" binding:"email,required"` 
    Password string `json:"password" form:"password" binding:"required"` 
} 

Router

router.POST("/login",middlewares.Validator(LoginForm{}) ,controllers.Login) 

Middleware

func Validator(v interface{}) gin.HandlerFunc{ 
    return func(c *gin.Context){ 
     a := reflect.New(reflect.TypeOf(v)) 
     err:=c.Bind(&a) 
     if(err!=nil){ 
      respondWithError(401, "Login Error", c) 
      return 
     } 
     c.Set("LoginForm",a) 
     c.Next() 
    } 
} 

Ich bin sehr neu golang. Ich verstehe das Problem mit der Bindung an die falsche Variable. Gibt es eine andere Möglichkeit, dies zu lösen?

+1

Pass in einer Fabrik und nicht als Modellvariable. 'Typ ViewFactory func() Schnittstelle {}' –

+0

Es tut mir leid, habe ich nicht verstanden. Kannst du bitte mehr erklären oder einen Link zum Lesen geben? –

Antwort

0

Clarify mein Kommentar,

Statt die Unterschrift mit func Validator(v interface{}) gin.HandlerFunc für die MW, verwenden func Validator(f Viewfactory) gin.HandlerFunc

Wo ViewFactory, wenn eine Funktion Typ wie type ViewFactory func() interface{}

die MW so

geändert werden kann
type ViewFactory func() interface{} 

func Validator(f ViewFactory) gin.HandlerFunc{ 
    return func(c *gin.Context){ 
     a := f() 
     err:=c.Bind(a) // I don t think you need to send by ref here, to check by yourself 
     if(err!=nil){ 
      respondWithError(401, "Login Error", c) 
      return 
     } 
     c.Set("LoginForm",a) 
     c.Next() 
    } 
} 

Sie können den Router so schreiben

type LoginForm struct{ 
    Email string `json:"email" form:"email" binding:"email,required"` 
    Password string `json:"password" form:"password" binding:"required"` 
} 
func NewLoginForm() interface{} { 
    return &LoginForm{} 
} 
router.POST("/login",middlewares.Validator(NewLoginForm) ,controllers.Login) 

geht weiter, ich denke, man muss später darüber erfahren können, wenn Sie einen interface{} Wert haben, können Sie es eine LoginForm wie diese v := some.(*LoginForm) machen zurück.

Oder so für mehr Sicherheit

if v, ok := some.(*LoginForm); ok { 
// v is a *LoginForm 
} 

See golang Typ Behauptungen für mehr ausführliche Informationen.

+0

Das funktioniert perfekt. Ich fand jedoch einen weiteren Weg, Ändern a: = reflect.New (reflect.TypeOf (v)) err: = c.Bind (& a) zu a: = reflect.New (reflect.TypeOf (v)). Interface() err: = c.Bind (a) –

+0

Ich fürchte, das funktioniert nur für den einfachen Fall wie Sie zuvor vorgestellt. Ich vermute stark, dass die Dinge viel komplexer werden, wenn Sie Slices, Maps, Chans oder Struct Pointers treffen. –

Verwandte Themen