gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.97k stars 8.02k forks source link

Access gin request Context from custom validators #2741

Open samber opened 3 years ago

samber commented 3 years ago

The StructValidator interface does not allow passing *gin.Context.

For example, I would like to access c.Params from my validator.

Current interface signature:

type StructValidator interface {
    ValidateStruct(interface{}) error
    Engine() interface{}
}

It would be very nice to add an interface such as:

type StructValidatorWithContext interface {
    ValidateStructWithContext(interface{}) error
    Engine() interface{}
}
kszafran commented 3 years ago

Related to this: https://github.com/gin-gonic/gin/issues/1489

I agree that this could be helpful. The validator library supports contextual validation if you call (*Validate).StructCtx(...) instead of (*Validate).Struct(...). I imagine that could be implemented by passing *gin.Context as the ctx argument since it implements context.Context.

For example, in my case, I'd like to make a field required or not, based on a query param. If gin context was passed on to the validator, I could do that.

I imagine the StructValidator validator could be extended with one more method:

ValidateStructCtx(context.Context, interface{}) error

Or if this cannot be done, because it's a breaking change, then an "extension" interface could be defined, similar to what @samber proposed:

type StructValidatorWithContext interface {
    StructValidator
    ValidateStructCtx(context.Context, interface{}) error
}

And then, when binding, the code could check if the validator implementation is an instance of StructValidatorWithContext. Kind of like the standard library sometimes checks if your io.Reader is also an io.ReadCloser.

kszafran commented 3 years ago

@samber Check out my PR. I implemented passing context to validators: https://github.com/gin-gonic/gin/pull/2877

kaysonwu commented 1 year ago

I have also encountered this issue, which can help enhance the form validation function. I look forward to going online soon.