go-fuego / fuego

Golang Fuego - web framework generating OpenAPI 3 spec from source code
https://go-fuego.github.io/fuego/
MIT License
917 stars 46 forks source link

Method based model validation #199

Closed mrg0lden closed 1 month ago

mrg0lden commented 1 month ago

Is your feature request related to a problem? Please describe. I dislike go-playground's validator for its error-prone nature and unreadablity due its reliance on struct-tags. I can see how struct tags are helpful for combining the documentation and validation, but my point still stands.

Describe the solution you'd like I propose defining an interface to allow method-based model validation. It'd look something like this

type Validatable interface {
    Validate() error
}

Defining the interface isn't even a requirement as it can be implemented similarly to Go's errors.Is behavior.

Describe alternatives you've considered The only alternative is go-playground/validator's unlikeable RegisterXXX functions.

Additional context On a side note, a way for models to define a method that describes their fields would also be cool.

EwenQuim commented 1 month ago

You can already do this using this syntax.

The interface exists and is called fuego.InTransformer. There's also a fuego.OutTransformer, just for transformation, on the output side.

It also allows transformation before validation, and is cumulable with struct tags.

type MyInput struct {
    Name string `json:"name" validate:"required"`
}

// Will be called just before returning c.Body()
func (r *MyInput) InTransform(context.Context) error {
    r.Name = strings.ToLower(r.Name)

    if r.Name == "fuego" {
        return errors.New("fuego is not a valid name for this input")
    }

    return nil
}

Not that it isn't recursive, if you have nested struct you need to call their validation function explicitely.

mrg0lden commented 1 month ago

Eh, it works I guess.