Skip to content

Jamess-Lucass/validator-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Validator-go


Zod inspired schema validation in Go.


CI Test Status License

Table of contents

Introduction

validator-go is a simple and extensible validation library for Go. It's heavily inspired by Zod and shares a lot of the same interfaces. This library provides a set of validation schemas for different data types, such as integers, strings, and booleans, and allows you to refine these schemas with custom validation rules.

Installation

Ensure you have Go installed (download). Version 1.21 or higher is required.

go get -u github.com/Jamess-Lucass/validator-go

Basic usage

Creating a string schema

import (
    schema "github.com/Jamess-Lucass/validator-go"
)

// Creating a schema for strings
mySchema := schema.String();

// Parsing
mySchema.Parse("john"); // => *schema.ValidationResult
mySchema.Parse("john").IsValid(); // => true
mySchema.Parse(12).Errors; // => []

mySchema.Parse(12).IsValid(); // => false
mySchema.Parse(12).Errors; // => [{ "path": "", "message": "Expected string, received int" }]

Creating an object schema

import (
    schema "github.com/Jamess-Lucass/validator-go"
)

// Creating a schema for an object
mySchema := schema.Object(map[string]schema.ISchema{
    "Username": schema.String().Min(5),
})

// Parsing
type User struct {
    Username string
}

user1 := User{
    Username: "john_doe",
}

mySchema.Parse(user1).IsValid(); // => true
mySchema.Parse(user1).Errors; // => []

user2 := User{
    Username: "john",
}
mySchema.Parse(user2).IsValid(); // => false
mySchema.Parse(user2).Errors; // => [{ "path": "Firstname","message": "String must contain at least 5 character(s)" }]

Primitives

schema.String()
schema.Int()
schema.Bool()

Literals

john := schema.Literal("john");
four := schema.Literal(4);
trueSchema := schema.Literal(true);

Strings

schema.String().Max(2)
schema.String().Min(2)
schema.String().Length(2)
schema.String().Url()
schema.String().Includes(string)
schema.String().StartsWith(string)
schema.String().EndsWith(string)

Ints

schema.Int().Lt(2)
schema.Int().Lte(2)
schema.Int().Gt(2)
schema.Int().Gte(2)

schema.Int().Positive() // > 0
schema.Int().Nonnegative() // >= 0
schema.Int().Negative() // < 0
schema.Int().Nonpositive() // <= 0

schema.Int().MultipleOf(2)

Float64

The same methods are available on Float64 as ints

Booleans

schema.Bool()

Objects

mySchema := schema.Object(map[string]schema.ISchema{
    "Username": schema.String().Min(5),
    "Firstname": schema.String().Min(2).Max(128),
    "Age": schema.Int().Gte(18),
    "IsVerified": schema.Bool(),
})

Arrays

The array schema accepts any type that implements the ISchema interface, this allows you to parse in other schema.

mySchema := schema.Array(schema.String().Min(2)).Max(4)

The above schema defines an array of strings, each of which has a minimum length of 2, with the overall array max length of 4.

You may utilize array and object to construct a more advanced schema

mySchema := schema.Object(map[string]schema.ISchema{
    "Username": schema.String().Min(5),
    "Firstname": schema.String().Min(2).Max(128),
    "Age": schema.Int().Gte(18),
    "Addresses": schema.Array(schema.Object(map[string]schema.ISchema{
        "Postcode": schema.String().Min(4).Max(10),
        "Country": schema.String().Length(2),
    })),
})

Schema methods

All schemas contain certain methods.

.Parse

Given any schema, you may call the .Parse method and pass through any data to check it's validity against the schema.

mySchema := schema.String()

mySchema.Parse("john"); // => *schema.ValidationResult

mySchema.Parse("john").IsValid(); // => true
mySchema.Parse(2).Errors; // => []

mySchema.Parse(2).IsValid(); // => false
mySchema.Parse(2).Errors; // => [{ "path": "", "message": "Expected string, received int" }]

.Refine

You may provide custom validation logic with the .Refine method. This method must return true or false to represent whether validation should be considered successful or unsuccessful.

mySchema := schema.String().Refine(func(value string) bool {
    return value == "custom_value"
})

This is helpful if you need to perform some business-level validation. For example, checking a database for some value or making a HTTP request to assert something.

verifiedUserSchema := schema.String().Refine(func(value string) bool {
    // Fetch user from data.
    // ensure `is_verified` field is true.
    return true
})

This may also be used in conjunction with .Object

type User struct {
    Firstname string
    Lastname  string
    Age       int
}

user := User{
    Firstname: "john",
    Lastname:  "doe",
    Age:       10,
}

mySchema := schema.Object(map[string]schema.ISchema{
    "Firstname": schema.String().Refine(func(value string) bool {
        return value == "john" || value == "jane"
    }),
    "Lastname": schema.String().Refine(func(value string) bool {
        return strings.Contains(value, "doe")
    }),
    "Age": schema.Int().Lt(10),
}).Refine(func(value map[string]interface{}) bool {
    if value["Firstname"] == "jane" {
        if age, ok := value["Age"].(int); ok {
            return age < 5
        }
    }

    return true
})