I would like to make a reusable middleware for validation throughout my API. Here, validation is done through govalidator, so I just need to pass the validation rules and a DTO where the request is mapped into.
func ValidationMiddleware(next http.HandlerFunc, validationRules govalidator.MapData, dto interface{}) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
utils.SetResponseHeaders(rw)
opts := govalidator.Options{
Request: r,
Data: &dto,
Rules: validationRules,
RequiredDefault: true,
}
v := govalidator.New(opts)
err := v.ValidateJSON()
if err != nil {
fmt.Println("Middleware found an error")
err := utils.ErrorWrapper{
StatusCode: 400,
Type: "Bad Request",
Message: err,
}
err.ThrowError(rw)
return
}
next(rw, r)
}
}
This is how the HandleFunc
looks like:
var rules govalidator.MapData = govalidator.MapData{
"name": []string{"required"},
"description": []string{"required"},
"price": []string{"required", "float"},
}
func RegisterItemsRouter(router *mux.Router) {
itemsRouter := router.PathPrefix("/inventory").Subrouter()
itemsRouter.HandleFunc("/", middleware.ValidationMiddleware(addItem, rules, dto.CreateItem{
Name: "",
Description: "",
Price: govalidator.Float64{},
})).Methods("POST")
}
If no errors are found, govalidator parses the request body into the dto struct, so I would like to pass this down into the next handler and avoid trying to parse the body a second time.
How can I pass this struct down to the next HandleFunc?