validator icon indicating copy to clipboard operation
validator copied to clipboard

Expose baked in validators for use with custom validators

Open AaronRobson opened this issue 3 years ago • 6 comments

  • [x] I have looked at the documentation here first?
  • [x] I have looked at the examples provided that may showcase my question here?

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

Enhancement - to allow custom validators to use the baked in ones as building blocks (https://github.com/go-playground/validator/blob/d4271985b44b735c6f76abc7a06532ee997f9476/baked_in.go#L477)

If the isUuid etc. functions started with a capital letter (i.e. IsUuid etc.) they'd be available to users of the library.

Code sample, to showcase or reproduce:

package main

import (
	"strings"

	"github.com/go-playground/validator/v10"
)

type Example struct {
	Value string `json:"value" validate:"required"`
}

// use a single instance of Validate, it caches struct info
var validate *validator.Validate

func main() {
	validate = validator.New()
	validate.RegisterValidation("uuidwithprefix", validateUuidWithPrefix)

	s := Example{Value: "invalid|74a740c3-ef1d-4333-9f28-930ed602590d"}
	err := validate.Struct(s)
	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}

	s.String = "expected-prefix|74a740c3-ef1d-4333-9f28-930ed602590d"
	err = validate.Struct(s)
	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}
}

func validateUuidWithPrefix(fl validator.FieldLevel) bool {
	parts := string.Split(fl.Field().String(), "|")
 	if len(parts) != 2 {
		return false
	}
	if parts[0] != "expected-prefix" {
		return false
	}
	return validators.isUuid(parts[1])  <- This fails as isUuid is not exposed by the library
}

Modelled after: https://github.com/go-playground/validator/blob/master/_examples/custom-validation/main.go

AaronRobson avatar Sep 29 '21 09:09 AaronRobson

Hey @AaronRobson this is not the first time I've gotten this requisition for various reasons. I can see how having these functions exposed could be beneficial.

My main concern is that it would dramatically increase the surface area of this library.

WDYT if I created a separate repo with these raw exposed validations and then changed this lib to use it? then can get the best of both worlds?

deankarn avatar Oct 23 '21 22:10 deankarn

Sounds like a good solution to me. Thank you for the consideration.

AaronRobson avatar Oct 28 '21 00:10 AaronRobson

It's unclear to me, what was the resolution of this? I bumped into the same situation.

I have a string of comma separated country codes that is omitempty but I also want to be able to validate it as a 2 letter country code list with iso3166_1_alpha2. I cannot just put the baked in validator because the comma separated list is not seen as an array for dive.

AdrianCio avatar Jan 25 '23 11:01 AdrianCio

My main concern is that it would dramatically increase the surface area of this library.

This functions are not exposed as go functions but if implementation of for example isUuid was changed in a braking way, it will be braking change for the lib as well. So this means to me that validations are already part of api surface of this library.

safareli avatar Dec 17 '23 16:12 safareli

@deankarn We can use specific baked-in tags to trigger specific baked-in validation functions associated with the tags. How validations work is already part of the API.

By exposing baked-in functions, what's increased in the surface area is that users can now use validations not only on struct fields but also on everything they are concerned about. I think that the following are all safe to be exposed:

  1. The tag aaaa calls the function IsAAAA.
  2. The function IsAAAA has a specific signature (namely, func (FieldLevel) bool)

zzJinux avatar Mar 15 '24 07:03 zzJinux