Home

Awesome

<div align="center"> <br /> <a href="https://github.com/Oudwins/zog"> <img src="https://raw.githubusercontent.com/Oudwins/zog/master/assets/zog-banner.png" alt="Zog, a Zod-like schema parser & validator" /> </a> </div>

ZOG - A Zod & Yup like Schema Parser & Validator for GO

Coverage Status Go Report Card GitHub tag <a href="https://pkg.go.dev/github.com/Oudwins/zog"><img src="https://pkg.go.dev/badge/github.com//github.com/Oudwins/tailwind-merge-go.svg" alt="Go Reference" /></a> License: MIT

Mentioned in Awesome Go Mentioned in Awesome Templ stars - zog

view - Documentation

Zog is a schema builder for runtime value parsing and validation. Define a schema, transform a value to match, assert the shape of an existing value, or both. Zog schemas are extremely expressive and allow modeling complex, interdependent validations, or value transformations. Checkout the full docs at https://zog.dev

Killer Features:

API Stability:

Introduction

0. Read the docs at zog.dev

Or don't, below is the quickstart guide

1 Install

go get github.com/Oudwins/zog

2 Create a user schema and its struct

import (
  z "github.com/Oudwins/zog"
   )


type User struct {
  Name string `zog:"firstname"` // tag is optional. If not set zog will check for "name" field in the input data
  Age int
}

var userSchema = z.Struct(z.Schema{
  // its very important that schema keys like "name" match the struct field name NOT the input data
  "name": z.String().Min(3, z.Message("Override default message")).Max(10),
  "age": z.Int().GT(18).Required(z.Message("is required")),
})

3 Parse into the struct

func main() {
  u := User{}
  m := map[string]string{
    "firstname": "Zog", // Note we are using "firstname" here as specified in the struct tag
    "age": "", // won't return an error because fields are optional by default
  }
  errsMap := schema.Parse(m, &u)
  if errsMap != nil {
    // handle errors -> see Errors section
  }
  u.Name // "Zog"
  // note that this might look weird but we didn't say age was required so Zog just skiped the empty string and we are left with the uninitialized int
  u.Age // 0
}

4. Its easy to use with http

The zhttp package has you covered for JSON, Forms and Query Params, just do:

import (
  zhttp "github.com/Oudwins/zog/zhttp"
   )
err := userSchema.Parse(zhttp.Request(r), &user)

5. Or to validate your environment variables

The zenv package has you covered, just do:

import (
  zenv "github.com/Oudwins/zog/zenv"
   )
err := envSchema.Parse(zenv.NewDataProvider(), &envs)

6. You can also parse individual fields

var t = time.Time
errsList := Time().Required().Parse("2020-01-01T00:00:00Z", &t)

7 And do stuff before and after parsing

var dest []string
Slice(String().Email().Required()).PreTransform(func(data any, ctx z.ParseCtx) (any, error) {
  s := val.(string)
  return strings.Split(s, ","), nil
}).PostTransform(func(destPtr any, ctx z.ParseCtx) error {
  s := val.(*[]string)
  for i, v := range s {
    s[i] = strings.TrimSpace(v)
  }
  return nil
}).Parse("foo@bar.com,bar@foo.com", &dest) // dest = [foo@bar.com bar@foo.com]

Roadmap

These are some of the things I want to add to zog before v1.0.0

Support

The damm domain costs me some outrageous amount like 100$ a year, so if any one wants to help cover that cost through github sponsors that is more than welcome.

Acknowledgments

License

This project is licensed under the MIT License - see the LICENSE file for details.