Closed ddysher closed 6 years ago
Research on existing solutions
repo | stars | import by | tag support | unique feature |
---|---|---|---|---|
go-playground/validator | 1193 | 54 | yes | inborn cross fields validate; i18n |
go-validator/validator | 664 | 204 | yes | support regexp |
go-ozzo/ozzo-validation | 431 | 12 | no | no struct tags |
asaskevich/govalidator | 2076 | 334 | yes | with some helper functions; support regexp |
also need support for query validation
package validator
// Validatable can be implemented by custom structs.
// Custom structs then are able to be checked by validator.
// Exp:
// type User struct {
// Name string
// Age int
// }
// func (u User) Validate() *ValidateError {
// if u.Name != "me" {
// return &ValidateError{Field: "name", Value: u.Name, Reason: "not me"}
// }
// return nil
// }
type Validatable interface {
Validate() *ValidateError
}
// ValidateError is used to keep error format consistent with otheres.
// Should we add a method to convert it to nirvana.Error?
type ValidateError struct {
Field string
Value interface{}
Reason string
}
package validator
import (
"net/http"
// 2 helpful binding pkg
// "github.com/go-playground/form"
// "github.com/gorilla/schema"
)
// WithBinding works like json.Unmarshal. It will parse the content to v and
// then validate v.
// Questions:
// If r.Body has content, then it must be json bytes? Or yaml? Or guess from content?
// What is the query param format? exp: how to define array in query params?
func WithBinding(r *http.Request, v interface{}) error {
return nil
}
@Jimexist Do you mean query param validation? If so, yes.
@walktall Action Items after second meeting:
@walktall Action Items after 4th meeting:
How to implement sample:
// Package validator usage:
// type Application struct {
// Name string `json:"name" validate:"required,printascii"`
// Namespace string `json:"namespace"`
// }
// Definitions: []definition.Definition{
// {
// Method: definition.Create,
// Function: Handle,
// Parameters: []definition.Parameter{
// {
// Source: definition.Query,
// Name: "target1",
// Operators: []definition.Operator{validator.Var("gt=0,lt=10")},
// },
// {
// Source: definition.Body,
// Name: "app",
// // Should we call this automatically?
// Operators: []definition.Operator{validator.Struct()},
// },
// },
// },
// },
package validator
import (
"context"
"gopkg.in/go-playground/validator.v9"
)
var std = validator.New()
func Var(tag string) func(ctx context.Context, object interface{}) (interface{}, error) {
return func(ctx context.Context, object interface{}) (interface{}, error) {
// TODO: error format
return object, std.VarCtx(ctx, object, tag)
}
}
func VarWithValue(other interface{}, tag string) func(ctx context.Context, object interface{}) (interface{}, error) {
return func(ctx context.Context, object interface{}) (interface{}, error) {
err := std.VarWithValueCtx(ctx, object, other, tag)
return object, err
}
}
func Struct() func(ctx context.Context, object interface{}) (interface{}, error) {
return func(ctx context.Context, object interface{}) (interface{}, error) {
return object, std.StructCtx(ctx, object)
}
}
Action Items after 5th meeting:
Done 🚀
Umbrella issue for tracking API validation tasks, scopes:
@walktall