Home

Awesome

vjson

codecov Go Report Card <miladibra10> Go Reference

vjson is a Go package that helps to validate JSON objects in a declarative way.

Getting Started

Installing

For installing vjson, use command below:

go get -u github.com/miladibra10/vjson

Concepts

There are two main concepts in vjson that are:

Schema

A schema is the holder of JSON object specifications. It contains the way of validation of a JSON object. a schema consists of an array of fields.

Field

A field contains characteristics of a specific field of a json object. multiple field types are supported by vjson. list of supported types are:

How to create a Schema

There are two ways to create a schema.

Schema in code

Schema could be declared in code like this:

package main

import "github.com/miladibra10/vjson"

func main() {
	schema := vjson.NewSchema(
		vjson.String("name").Required(),
	)

	jsonString := `
	{
		"name": "James"
	}
	`

	err := schema.ValidateString(jsonString)
	if err != nil {
		panic(err)
	}
}

schema object contains a string field, named name. This code validates jsonString.

Parse Schema

Schema could be parsed from a file or a string. These methods help to parse schema.

Format of schema for parsing should be a json like this:

{
  "fields": [
    ...
  ]
}

fields should contain field specifications.

This code parses a schema from string:

package main

import "github.com/miladibra10/vjson"

func main() {
	schemaStr := `
	{
		"fields": [
			{
				"name": "name",
				"type": "string"
				"required": true
			}
		]
	}
	`
	schema, err := vjson.ReadFromString(schemaStr)
	if err != nil {
		panic(err)
	}

	jsonString := `
	{
		"name": "James"
	}
	`

	err = schema.ValidateString(jsonString)
	if err != nil {
		panic(err)
	}
}

schemaStr describes the schema and vjson.ReadFromString(schemaStr) parses the string and returns a schema object.

schema object contains a string field, named name. This code validates jsonString.

Note: You could Marshal your schema as a json object for backup usages with json.Marshal function.

Fields

Integer

An integer field could be created in code like this:

vjson.Integer("foo")

some validation characteristics could be added to an integer field with chaining some functions:

integer field could be described by a json for schema parsing.

Example

an integer field, named foo which is required, minimum value should be 2, maximum value should be 10, should be positive and be within range [3,5] or [6,8] ,could be declared like this:

Code

vjson.Integer("foo").Required().Min(2).Max(10).Positive().Range(3,5).Range(6,8)

File

{
  "name": "foo",
  "type": "integer",
  "required": true,
  "min": 2,
  "max": 10,
  "positive": true,
  "ranges": [
    {
      "start": 3,
      "end": 5
    },
    {
      "start": 6,
      "end": 8
    }
  ]
}

Float

A float field could be created in code like this:

vjson.Float("foo")

some validation characteristics could be added to a float field with chaining some functions:

float field could be described by a json for schema parsing.

Example

a float field, named foo which is required, minimum value should be 2.5, maximum value should be 10.5, should be positive and be within range [3,5] or [6,8] ,could be declared like this:

Code

vjson.Float("foo").Required().Min(2.5).Max(10.5).Positive().Range(3,5).Range(6,8)

File

{
  "name": "foo",
  "type": "float",
  "required": true,
  "min": 2.5,
  "max": 10.5,
  "positive": true,
  "ranges": [
    {
      "start": 3,
      "end": 5
    },
    {
      "start": 6,
      "end": 8
    }
  ]
}

String

A string field could be created in code like this:

vjson.String("foo")

some validation characteristics could be added to a string field with chaining some functions:

float field could be described by a json for schema parsing.

Example

a string field, named foo which is required, minimum length value should be 2, maximum length value should be 10, should be Equal to one of these values: first, second could be declared like this:

Code

vjson.String("foo").Required().MinLength(2).MaxLength(10).Choices("first", "second")

File

{
  "name": "foo",
  "type": "string",
  "required": true,
  "min_length": 2,
  "max_length": 10,
  "choices": [
    "first",
    "second"
  ]
}

Boolean

A boolean field could be created in code like this:

vjson.Boolean("foo")

some validation characteristics could be added to a boolean field with chaining some functions:

boolean field could be described by a json for schema parsing.

Example

a boolean field, named foo which is required, and always should be false, could be declared like this:

Code

vjson.Boolean("foo").Required().ShouldBe(false)

File

{
  "name": "foo",
  "type": "boolean",
  "required": true,
  "value": false
}

Array

An array field could be created in code like this:

vjson.Array("foo", vjson.String("item"))

the first argument is the name of array field, and the second one is the field characteristics of each item of array.

some validation characteristics could be added to an array field with chaining some functions:

array field could be described by a json for schema parsing.

Example

an array field, named foo with integer items between [0,20] range, which is required, and its length should be at least 2 and at last 10, could be declared like this:

Code

vjson.Array("foo", vjson.Integer("item").Range(0,20)).Required().MinLength(2).MaxLength(10)

File

{
  "name": "foo",
  "type": "array",
  "required": true,
  "min_length": 2,
  "max_length": 10,
  "items": {
    "name": "item",
    "type": "integer",
    "ranges": [
      {
        "start": 0,
        "end": 20
      }
    ]
  }
}

Object

An object field could be created in code like this:

vjson.Object("foo", vjson.NewSchema(
        /// Fields	
	))

the first argument is the name of object field, and the second one is the schema of object value. this feature helps validation of nested json objects

some validation characteristics could be added to an array field with chaining some functions:

object field could be described by a json for schema parsing.

Example

a required object field, named foo which its valid value is an object with name and last_name required strings, could be declared like this:

Code

vjson.Object("foo", vjson.NewSchema(
	vjson.String("name").Required(),
	vjson.String("last_name").Required(),
	)).Required()

File

{
  "name": "foo",
  "type": "object",
  "required": true,
  "schema": {
    "fields": [
      {
        "name": "name",
        "type": "string",
        "required": true
      },
      {
        "name": "last_name",
        "type": "string",
        "required": true
      }
    ]
  }
}

Null

A null field (a field that its value should be null!) could be created in code like this:

vjson.Null("foo")

null field could be described by a json for schema parsing.

Example

a null field, named foo, could be declared like this:

Code

vjson.Null("foo")

File

{
  "name": "foo",
  "type": "null"
}

Validation

After creating a schema, you can validate your json objects with these methods:

Example

This code validates an object that should have name and age fields.

package main

import "github.com/miladibra10/vjson"

func main() {
	schema := vjson.NewSchema(
		vjson.String("name").Required(),
		vjson.Integer("age").Positive(),
	)

	jsonString := `
	{
		
  "required": true,
  "value": false"name": "James"
	}
	`

	err := schema.ValidateString(jsonString)
	if err != nil {
		panic(err) // Will not panic
	}

	jsonString = `
	{
		"name": "James",
        "age": 10
	}
	`

	err = schema.ValidateString(jsonString)
	if err != nil {
		panic(err) // Will not panic
	}

	jsonString = `
	{
        "age": 10
	}
	`

	err = schema.ValidateString(jsonString)
	if err != nil {
		panic(err) // Will panic because name field is missing in jsonString
	}
	
}

Benchmarks

Results of benchmarking validation functions highly depends on types and number of fields.

two simple benchmarks (exists in schema_test.go file) with using all features of vjson gives this result:

goos: linux
goarch: amd64
pkg: github.com/miladibra10/vjson
BenchmarkSchema_ValidateString-8          416664              2792 ns/op
BenchmarkSchema_ValidateBytes-8           431734              2858 ns/op
PASS
ok      github.com/miladibra10/vjson    2.461s