README.md
1[![Build Status](https://travis-ci.org/xeipuuv/gojsonschema.svg)](https://travis-ci.org/xeipuuv/gojsonschema)
2
3# gojsonschema
4
5## Description
6
7An implementation of JSON Schema, based on IETF's draft v4 - Go language
8
9References :
10
11* http://json-schema.org
12* http://json-schema.org/latest/json-schema-core.html
13* http://json-schema.org/latest/json-schema-validation.html
14
15## Installation
16
17```
18go get github.com/xeipuuv/gojsonschema
19```
20
21Dependencies :
22* [github.com/xeipuuv/gojsonpointer](https://github.com/xeipuuv/gojsonpointer)
23* [github.com/xeipuuv/gojsonreference](https://github.com/xeipuuv/gojsonreference)
24* [github.com/stretchr/testify/assert](https://github.com/stretchr/testify#assert-package)
25
26## Usage
27
28### Example
29
30```go
31
32package main
33
34import (
35 "fmt"
36 "github.com/xeipuuv/gojsonschema"
37)
38
39func main() {
40
41 schemaLoader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json")
42 documentLoader := gojsonschema.NewReferenceLoader("file:///home/me/document.json")
43
44 result, err := gojsonschema.Validate(schemaLoader, documentLoader)
45 if err != nil {
46 panic(err.Error())
47 }
48
49 if result.Valid() {
50 fmt.Printf("The document is valid\n")
51 } else {
52 fmt.Printf("The document is not valid. see errors :\n")
53 for _, desc := range result.Errors() {
54 fmt.Printf("- %s\n", desc)
55 }
56 }
57
58}
59
60
61```
62
63#### Loaders
64
65There are various ways to load your JSON data.
66In order to load your schemas and documents,
67first declare an appropriate loader :
68
69* Web / HTTP, using a reference :
70
71```go
72loader := gojsonschema.NewReferenceLoader("http://www.some_host.com/schema.json")
73```
74
75* Local file, using a reference :
76
77```go
78loader := gojsonschema.NewReferenceLoader("file:///home/me/schema.json")
79```
80
81References use the URI scheme, the prefix (file://) and a full path to the file are required.
82
83* JSON strings :
84
85```go
86loader := gojsonschema.NewStringLoader(`{"type": "string"}`)
87```
88
89* Custom Go types :
90
91```go
92m := map[string]interface{}{"type": "string"}
93loader := gojsonschema.NewGoLoader(m)
94```
95
96And
97
98```go
99type Root struct {
100 Users []User `json:"users"`
101}
102
103type User struct {
104 Name string `json:"name"`
105}
106
107...
108
109data := Root{}
110data.Users = append(data.Users, User{"John"})
111data.Users = append(data.Users, User{"Sophia"})
112data.Users = append(data.Users, User{"Bill"})
113
114loader := gojsonschema.NewGoLoader(data)
115```
116
117#### Validation
118
119Once the loaders are set, validation is easy :
120
121```go
122result, err := gojsonschema.Validate(schemaLoader, documentLoader)
123```
124
125Alternatively, you might want to load a schema only once and process to multiple validations :
126
127```go
128schema, err := gojsonschema.NewSchema(schemaLoader)
129...
130result1, err := schema.Validate(documentLoader1)
131...
132result2, err := schema.Validate(documentLoader2)
133...
134// etc ...
135```
136
137To check the result :
138
139```go
140 if result.Valid() {
141 fmt.Printf("The document is valid\n")
142 } else {
143 fmt.Printf("The document is not valid. see errors :\n")
144 for _, err := range result.Errors() {
145 // Err implements the ResultError interface
146 fmt.Printf("- %s\n", err)
147 }
148 }
149```
150
151## Working with Errors
152
153The library handles string error codes which you can customize by creating your own gojsonschema.locale and setting it
154```go
155gojsonschema.Locale = YourCustomLocale{}
156```
157
158However, each error contains additional contextual information.
159
160**err.Type()**: *string* Returns the "type" of error that occurred. Note you can also type check. See below
161
162Note: An error of RequiredType has an err.Type() return value of "required"
163
164 "required": RequiredError
165 "invalid_type": InvalidTypeError
166 "number_any_of": NumberAnyOfError
167 "number_one_of": NumberOneOfError
168 "number_all_of": NumberAllOfError
169 "number_not": NumberNotError
170 "missing_dependency": MissingDependencyError
171 "internal": InternalError
172 "enum": EnumError
173 "array_no_additional_items": ArrayNoAdditionalItemsError
174 "array_min_items": ArrayMinItemsError
175 "array_max_items": ArrayMaxItemsError
176 "unique": ItemsMustBeUniqueError
177 "array_min_properties": ArrayMinPropertiesError
178 "array_max_properties": ArrayMaxPropertiesError
179 "additional_property_not_allowed": AdditionalPropertyNotAllowedError
180 "invalid_property_pattern": InvalidPropertyPatternError
181 "string_gte": StringLengthGTEError
182 "string_lte": StringLengthLTEError
183 "pattern": DoesNotMatchPatternError
184 "multiple_of": MultipleOfError
185 "number_gte": NumberGTEError
186 "number_gt": NumberGTError
187 "number_lte": NumberLTEError
188 "number_lt": NumberLTError
189
190**err.Value()**: *interface{}* Returns the value given
191
192**err.Context()**: *gojsonschema.jsonContext* Returns the context. This has a String() method that will print something like this: (root).firstName
193
194**err.Field()**: *string* Returns the fieldname in the format firstName, or for embedded properties, person.firstName. This returns the same as the String() method on *err.Context()* but removes the (root). prefix.
195
196**err.Description()**: *string* The error description. This is based on the locale you are using. See the beginning of this section for overwriting the locale with a custom implementation.
197
198**err.Details()**: *gojsonschema.ErrorDetails* Returns a map[string]interface{} of additional error details specific to the error. For example, GTE errors will have a "min" value, LTE will have a "max" value. See errors.go for a full description of all the error details. Every error always contains a "field" key that holds the value of *err.Field()*
199
200Note in most cases, the err.Details() will be used to generate replacement strings in your locales. and not used directly i.e.
201```
202%field% must be greater than or equal to %min%
203```
204
205## Formats
206JSON Schema allows for optional "format" property to validate strings against well-known formats. gojsonschema ships with all of the formats defined in the spec that you can use like this:
207````json
208{"type": "string", "format": "email"}
209````
210Available formats: date-time, hostname, email, ipv4, ipv6, uri.
211
212For repetitive or more complex formats, you can create custom format checkers and add them to gojsonschema like this:
213
214```go
215// Define the format checker
216type RoleFormatChecker struct {}
217
218// Ensure it meets the gojsonschema.FormatChecker interface
219func (f RoleFormatChecker) IsFormat(input string) bool {
220 return strings.HasPrefix("ROLE_", input)
221}
222
223// Add it to the library
224gojsonschema.FormatCheckers.Add("role", RoleFormatChecker{})
225````
226
227Now to use in your json schema:
228````json
229{"type": "string", "format": "role"}
230````
231
232## Uses
233
234gojsonschema uses the following test suite :
235
236https://github.com/json-schema/JSON-Schema-Test-Suite
237