Framework: Is there an interface which encompasses all validator interfaces?

I’ve got a validator which satisfies a bunch of different validator interfaces. It seems silly to specify type specific helper functions to instantiate those validators.

For example, stringvalidator.AtLeastOneOf() and boolvalidator.AtLeastOneOf() make sense because while those helper functions share the same name, they live in different packages and have different signatures.

My AtMostNOfValidator{} satisfies all of the same interfaces, but the helper functions became a clunky problem because I don’t have packages dedicated to instantiating validators for each type (bool, string, etc…)

I came up with:

type NineTypesValidator interface {

var _ NineTypesValidator = AtMostNOfValidator{}

func AtMostNOf(n int, expressions ...path.Expression) NineTypesValidator {
	return AtMostNOfValidator{
		N:               n,
		PathExpressions: expressions,

Now I can use AtMostNOf() on schema attributes of any type.

But that NineTypesValidator is some silly nonsense.

Is there an existing interface I can lean on which covers the same problem?

If so, how could I have discovered that fact on my own?


Hey @hQnVyLRx :wave:

The choice of whether custom validation logic uses a helper functions on top of the Go type that implements the framework interfaces is a choice we made with the framework validators to reduce the likelihood that developers might not implement something correctly (preferring compiler errors over runtime errors). There’s no requirement that those functions be created.

For example, you should be able to write out struct implementations directly:

// This example validator implements any necessary interfaces,
// however that code is not shown for brevity.
type exampleValidator struct { /* ... */ }

// Example schema
  // ...
  Validators: []validator.String{
    exampleValidator{ /* ... */ },

That being said, the framework doesn’t provide something like your NineTypesValidator interface at the moment, but it probably should to simplify this sort of provider-defined code. If your willing/able, please feel free to create a feature request in the terraform-plugin-framework GitHub issues and submitting a pull request. I personally might encourage saying it should be an All or Any interface type in the generic validator package where the other typed interfaces live. :+1:

Hi @bflad,

Roger that. Yep, I blindly implemented the helper function without even thinking about it. Of course I could have dropped an instance of the validator struct into the appropriate slice in the schema. :slight_smile:

When you said All or Any here, I think you’re referring to the interface name. Something like ValidateAny, and not some complicated abstraction related to Go generics… Please confirm?

“nine types” was silly, of course, but I was wary of making any bold “all” claims without knowing about exciting new types might appear in the framework in the future.

Ultimately, that embarrassing interface name was what drove me here to ask the question.

If you’re proposing an 11 line PR, I’m happy to send it over.

Along those lines, you hinted once about guidance for evaluating validators for inclusion in terraform-plugin-framework-validators. Has that appeared anywhere yet?

I’m using:

  • AtLeastNOf(n int, expressions ...path.Expression) (similar to AtLeastOneOf)
  • AtMostNOf(n int, expressions ...path.Expression) (same as above)
  • ParseIP(requireIPv4, requireIPv6 bool) (string validator for IPv4/v6 addresses)
  • ParseCIDR(requireIPv4, requireIPv6 bool) (string validator for IPv4/v6 CIDR blocks)
  • NotEqual(expression path.Expression) (I still owe some tests for this one)

Happy to share if they seem interesting enough to make the cut.

Thanks again!