Comments (4)
Well that took a while to figure out.
type defaultValidator struct {
once sync.Once
validate *validator.Validate
modifiers *mold.Transformer
}
and
func (v *defaultValidator) lazyinit() {
...
v.modifiers = mold.New()
v.modifiers.SetTagName("mod")
v.modifiers.Register("trim", app.TrimSpace)
}
did the job.
Only other thing I could not solve, is how to actually use RegisterStructLevel without much code duplication. Wanted to wrap sql.NullString, as trim does not work (with RegisterCustomTypeFunc from the validator in mind) when used with this (because hard conversion to string in trim I assume). So it was easier to just rewrite TrimSpace with a type switch.
from mold.
Oh my, I'm my own grave digger. Years later, same question, I even find my own answer that does not help myself. Is there an example how to register mold with current gin, current validator v10?
from mold.
This is how I integrated mold
with gin
, u could check it out:
- Define your own Binding, similar to
binding.JSONBinding
ofgin
import (
"context"
"encoding/json"
"errors"
"io"
"net/http"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/mold/v4/modifiers"
)
var conform = modifiers.New()
// customJSONBinding is mostly same as Gin JSON Binding, but it transforms data after decoding and before validating
type customJSONBinding struct{}
func (customJSONBinding) Name() string {
return "supplier custom json binding"
}
func (customJSONBinding) Bind(req *http.Request, obj any) error {
if req == nil || req.Body == nil {
return errors.New("invalid request")
}
return decodeJSON(req.Body, obj)
}
func decodeJSON(r io.Reader, obj any) error {
decoder := json.NewDecoder(r)
if binding.EnableDecoderUseNumber {
decoder.UseNumber()
}
if binding.EnableDecoderDisallowUnknownFields {
decoder.DisallowUnknownFields()
}
if err := decoder.Decode(obj); err != nil {
return err
}
if err := transform(obj); err != nil {
return err
}
return validate(obj)
}
func transform(obj any) error {
if conform == nil {
return nil
}
return conform.Struct(context.Background(), obj)
}
func validate(obj any) error {
if binding.Validator == nil {
return nil
}
return binding.Validator.ValidateStruct(obj)
}
- Use your custom binding with
ShouldBindWith
to usemold
// You have to init an instance of `customJSONBinding` to use
var customJSON = customJSONBinding{}
type Request struct {
Email string `json:"email" mod:"trim" binding:"required,email"`
Name string `json:"name" mod:"trim" binding:"required"`
}
func myHandler(c *gin.Context) {
var req Request
if err := c.ShouldBindWith(&req, customJSON); err != nil {
// Do smt...
}
}
from mold.
The solution by @aupous worked.
But, here is how I integrated mold
package with gin
without rewriting/duplicating the entire binding package codes to create a custom binding for JSON and Form binding.
I created a custom Validator to transform the data object before validating a struct and replacing the binding validator with my custom validator.
Create the custom validator:
// helpers/custom_validator_helper.go
package helpers
import (
"context"
"reflect"
"github.com/go-playground/mold/v4/modifiers"
"github.com/go-playground/validator/v10"
)
type CustomValidator struct {
validator *validator.Validate
}
func NewCustomValidator() *CustomValidator {
v := validator.New()
// Set the tag name to "binding", SetTagName allows for changing of the default tag name of 'validate'
v.SetTagName("binding")
// Register Tag Name Function to get json name as alternate names for StructFields.
v.RegisterTagNameFunc(func(fld reflect.StructField) string {
return fld.Tag.Get("json")
})
// Register custom validation tags if needed
v.RegisterValidation("customValidation", customValidationFunc)
return &CustomValidator{validator: v}
}
// ValidateStruct is called by Gin to validate the struct
func (cv *CustomValidator) ValidateStruct(obj interface{}) error {
// transform the object using mold before validating the struct
transformer := modifiers.New()
if err := transformer.Struct(context.Background(), obj); err != nil {
return err
}
// validate the struct
if err := cv.validator.Struct(obj); err != nil {
return err
}
return nil
}
// Engine is called by Gin to retrieve the underlying validation engine
func (cv *CustomValidator) Engine() interface{} {
return cv.validator
}
// Custom validation function
func customValidationFunc(fl validator.FieldLevel) bool {
// Custom validation logic here
return true
}
Call the custom validator and override the binding validator:
// main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
func main() {
router := gin.Default()
// Use custom validator
customValidator := helpers.NewCustomValidator() // Create a new instance of your custom validator
binding.Validator = customValidator // Set the binding.Validator to your custom validator
// Define your routes and handlers
// ...
// Run the server
router.Run(":8080")
}
Then bind your Struct to the request using any of the default binding method
type Request struct {
Email string `json:"email" mod:"trim" binding:"required,email"`
Name string `json:"name" mod:"trim" binding:"required"`
}
func myHandler(c *gin.Context) {
var req Request
if err := c.ShouldBind(&req); err != nil {
// Do smt...
}
}
from mold.
Related Issues (15)
- *string to nil if empty string HOT 9
- Register() on modifiers.New() HOT 1
- Is this a misprint? HOT 1
- Probable bugs HOT 3
- question: plans to port validator on top of this? HOT 2
- Email, maybe a new one? HOT 3
- Add it to awesome-go HOT 2
- URGENT: Embedded structs HOT 2
- Add support for "dive,keys,…,endkeys,dive" HOT 1
- `mod` tag vs `mold` tag? HOT 1
- Support for more transformers like "max length" on string etc HOT 3
- Maybe a bug, scrubs emails
- Struct func doesn't work on slice fields HOT 3
- Add docs for json tags list HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mold.