Input validation made easy for Go interface methods.

  • By null
  • Last update: Mar 15, 2023
  • Comments: 0


Go Reference

Input validation made easy for Go interface methods.


Make a custom build of protogo:

$ protogo build

Or build from a local fork:

$ protogo build
$ protogo validate -h
Usage: protogo validate <source-file> <interface-name>

  <source-file>       source file
  <interface-name>    interface name

  -h, --help             Show context-sensitive help.

      --out="."          output directory
      --fmt              whether to make the generated code formatted
      --custom=STRING    the declaration file of custom validators

Quick Start

NOTE: The following code is located in helloworld.

  1. Define the interface

    type Service interface {
        SayHello(ctx context.Context, name string) (message string, err error)
  2. Implement the service

    type Greeter struct{}
    func (g *Greeter) SayHello(ctx context.Context, name string) (string, error) {
        return "Hello " + name, nil
  3. Add the validation annotations

    type Service interface {
        // @schema:
        //   name: len(0, 10) && match(`^\w+$`)
        SayHello(ctx context.Context, name string) (message string, err error)
  4. Generate the validation middleware

    $ cd examples/helloworld
    $ protogo validate ./service.go Service
  5. Use the middleware for input validation

    func main() {
        var svc helloworld.Service = &helloworld.Greeter{}
        svc = helloworld.ValidateMiddleware(nil)(svc)
        message, err = svc.SayHello(context.Background(), "!Tracey")
        fmt.Printf("message: %q, err: %v\n", message, err)
        // Output:
        // message: "", err: name: INVALID(invalid format)

Validation Syntax

Operator / Validator Validating / Vext Equivalent(s) Example
! Not !lt(0)
&& All / And gt(0) && lt(10)
|| Any / Or eq(0) || eq(1)
nonzero Nonzero nonzero
zero Zero zero
len LenString / LenSlice len(0, 10)
runecnt RuneCount runecnt(0, 10)
eq Eq eq(1)
ne Ne ne(2)
gt Gt gt(0)
gte Gte gte(0)
lt Lt lt(10)
lte Lte lte(10)
xrange Range xrange(0, 10)
in In in(0, 1)
nin Nin nin("Y", "N")
match Match match(`^\w+$`)
email Email email
ip IP ip
time Time time("2006-01-02T15:04:05Z07:00")
_ A special validator that means to use the nested Schema() of the struct argument. _


See examples.


Check out the documentation.