github.com/kaptinlin/jsonschema@v0.4.6/docs/api.md (about) 1 # API Reference 2 3 Complete reference for all methods and types in the JSON Schema library. 4 5 ## Compiler 6 7 ### `NewCompiler() *Compiler` 8 9 Creates a new schema compiler with default settings. 10 11 ```go 12 compiler := jsonschema.NewCompiler() 13 ``` 14 15 ### `(*Compiler) Compile(schema []byte) (*Schema, error)` 16 17 Compiles a JSON schema from bytes. 18 19 ```go 20 schema, err := compiler.Compile([]byte(`{"type": "string"}`)) 21 ``` 22 23 ### `(*Compiler) CompileWithID(id string, schema []byte) (*Schema, error)` 24 25 Compiles a schema with a specific ID for referencing. 26 27 ```go 28 schema, err := compiler.CompileWithID("user.json", schemaBytes) 29 ``` 30 31 ### `(*Compiler) RegisterFormat(name string, fn FormatFunc) *Compiler` 32 33 Registers a custom format validator. 34 35 ```go 36 compiler.RegisterFormat("uuid", func(value string) bool { 37 _, err := uuid.Parse(value) 38 return err == nil 39 }) 40 ``` 41 42 ### `(*Compiler) UnregisterFormat(name string) *Compiler` 43 44 Removes a previously registered custom format from the compiler. If `AssertFormat` is 45 set to `true`, schemas that reference this format will fail validation; otherwise the 46 format annotation will be ignored. 47 48 ```go 49 // Remove a custom format 50 compiler.UnregisterFormat("uuid") 51 ``` 52 53 ### `(*Compiler) RegisterDefaultFunc(name string, fn DefaultFunc) *Compiler` 54 55 Registers a function for dynamic default value generation. 56 57 ```go 58 // Register built-in function 59 compiler.RegisterDefaultFunc("now", jsonschema.DefaultNowFunc) 60 61 // Register custom function 62 compiler.RegisterDefaultFunc("uuid", func(args ...any) (any, error) { 63 return uuid.New().String(), nil 64 }) 65 66 // Use in schema 67 schema := `{ 68 "properties": { 69 "id": {"default": "uuid()"}, 70 "timestamp": {"default": "now(2006-01-02)"} 71 } 72 }` 73 ``` 74 75 **Function signature**: `func(args ...any) (any, error)` 76 - Functions should handle argument parsing gracefully 77 - Return values are used as defaults during unmarshaling 78 - Errors cause fallback to literal string values 79 80 ## Schema 81 82 ### Validation Methods 83 84 #### `(*Schema) Validate(data interface{}) *EvaluationResult` 85 86 Validates data against the schema. Auto-detects input type. 87 88 ```go 89 result := schema.Validate(data) 90 if result.IsValid() { 91 // Valid data 92 } else { 93 // Handle errors 94 for field, err := range result.Errors { 95 fmt.Printf("%s: %s\n", field, err.Message) 96 } 97 } 98 ``` 99 100 #### `(*Schema) ValidateJSON(data []byte) *EvaluationResult` 101 102 Optimized validation for JSON bytes. 103 104 ```go 105 result := schema.ValidateJSON([]byte(`{"name": "John"}`)) 106 ``` 107 108 #### `(*Schema) ValidateStruct(data interface{}) *EvaluationResult` 109 110 Zero-copy validation for Go structs. 111 112 ```go 113 user := User{Name: "John", Age: 25} 114 result := schema.ValidateStruct(user) 115 ``` 116 117 #### `(*Schema) ValidateMap(data map[string]interface{}) *EvaluationResult` 118 119 Optimized validation for maps. 120 121 ```go 122 data := map[string]interface{}{"name": "John"} 123 result := schema.ValidateMap(data) 124 ``` 125 126 ### Unmarshal Methods 127 128 **Important**: Unmarshal methods do NOT perform validation. Always validate separately. 129 130 #### `(*Schema) Unmarshal(dst, src interface{}) error` 131 132 Unmarshals data into destination, applying default values from schema. 133 134 ```go 135 // Recommended workflow 136 result := schema.Validate(data) 137 if result.IsValid() { 138 var user User 139 err := schema.Unmarshal(&user, data) 140 if err != nil { 141 // Handle unmarshal error 142 } 143 } else { 144 // Handle validation errors 145 } 146 ``` 147 148 **Supported source types:** 149 - `[]byte` (JSON data) 150 - `map[string]interface{}` (parsed JSON object) 151 - Go structs and other types 152 153 **Supported destination types:** 154 - `*struct` (Go struct pointer) 155 - `*map[string]interface{}` (map pointer) 156 - Other pointer types 157 158 ### Schema Configuration Methods 159 160 #### `(*Schema) SetCompiler(compiler *Compiler) *Schema` 161 162 Sets a custom compiler for the schema and returns the schema for method chaining. 163 164 ```go 165 // Create custom compiler with functions 166 compiler := jsonschema.NewCompiler() 167 compiler.RegisterDefaultFunc("now", jsonschema.DefaultNowFunc) 168 compiler.RegisterDefaultFunc("uuid", generateUUID) 169 170 // Set compiler on schema 171 schema := jsonschema.Object( 172 jsonschema.Prop("id", jsonschema.String(jsonschema.Default("uuid()"))), 173 jsonschema.Prop("timestamp", jsonschema.String(jsonschema.Default("now()"))), 174 ).SetCompiler(compiler) 175 176 // Child schemas automatically inherit parent's compiler 177 ``` 178 179 #### `(*Schema) GetCompiler() *Compiler` 180 181 Returns the effective compiler for the schema with smart inheritance. 182 183 ```go 184 compiler := schema.GetCompiler() 185 186 // Inheritance order: 187 // 1. Current schema's compiler 188 // 2. Parent schema's compiler (recursive) 189 // 3. Default global compiler 190 ``` 191 192 **Use cases:** 193 - **Per-schema functions**: Isolate function registries for different schemas 194 - **Function inheritance**: Child schemas automatically use parent's compiler 195 - **Dynamic defaults**: Enable function-based default value generation 196 197 ## Validation Results 198 199 ### `*EvaluationResult` 200 201 #### `(*EvaluationResult) IsValid() bool` 202 203 Returns true if validation passed. 204 205 ```go 206 if result.IsValid() { 207 // Process valid data 208 } 209 ``` 210 211 #### `(*EvaluationResult) Errors map[string]*EvaluationError` 212 213 Map of validation errors by field path. 214 215 ```go 216 for field, err := range result.Errors { 217 switch err.Keyword { 218 case "required": 219 fmt.Printf("Missing: %s\n", field) 220 case "type": 221 fmt.Printf("Wrong type: %s\n", field) 222 default: 223 fmt.Printf("%s: %s\n", field, err.Message) 224 } 225 } 226 ``` 227 228 #### `(*EvaluationResult) ToList(includeHierarchy ...bool) *List` 229 230 Converts result to a flat list format. 231 232 ```go 233 list := result.ToList() 234 for field, message := range list.Errors { 235 fmt.Printf("%s: %s\n", field, message) 236 } 237 ``` 238 239 #### `(*EvaluationResult) ToLocalizeList(localizer *i18n.Localizer, includeHierarchy ...bool) *List` 240 241 Converts result with localized error messages. 242 243 ```go 244 i18nBundle, _ := jsonschema.GetI18n() 245 localizer := i18nBundle.NewLocalizer("zh-Hans") 246 list := result.ToLocalizeList(localizer) 247 ``` 248 249 ## Error Types 250 251 ### `*EvaluationError` 252 253 Validation error with detailed information. 254 255 #### Fields 256 - `Keyword string` - JSON Schema keyword that failed 257 - `Code string` - Error code for i18n 258 - `Message string` - Human-readable error message 259 - `Params map[string]interface{}` - Parameters for templating 260 261 #### `(*EvaluationError) Localize(localizer *i18n.Localizer) string` 262 263 Returns localized error message. 264 265 ### `*UnmarshalError` 266 267 Error during unmarshaling process. 268 269 #### Fields 270 - `Type string` - Error category ("destination", "source", "defaults", "unmarshal") 271 - `Field string` - Field that caused the error (if applicable) 272 - `Reason string` - Human-readable reason 273 - `Err error` - Wrapped underlying error 274 275 ```go 276 var unmarshalErr *jsonschema.UnmarshalError 277 if errors.As(err, &unmarshalErr) { 278 switch unmarshalErr.Type { 279 case "destination": 280 // Invalid destination (nil, not pointer, etc.) 281 case "source": 282 // Invalid source data 283 case "defaults": 284 // Error applying default values 285 case "unmarshal": 286 // Error during unmarshaling 287 } 288 } 289 ``` 290 291 ## Internationalization 292 293 ### `GetI18n() (*i18n.I18n, error)` 294 295 Returns the i18n bundle with supported locales. 296 297 ```go 298 i18nBundle, err := jsonschema.GetI18n() 299 if err != nil { 300 log.Fatal(err) 301 } 302 ``` 303 304 ### `(*i18n.I18n) NewLocalizer(locale string) *i18n.Localizer` 305 306 Creates a localizer for a specific locale. 307 308 ```go 309 localizer := i18nBundle.NewLocalizer("zh-Hans") 310 ``` 311 312 **Supported locales:** 313 - `en` - English 314 - `zh-Hans` - Simplified Chinese 315 - `zh-Hant` - Traditional Chinese 316 - `ja-JP` - Japanese 317 - `ko-KR` - Korean 318 - `fr-FR` - French 319 - `de-DE` - German 320 - `es-ES` - Spanish 321 - `pt-BR` - Portuguese (Brazil) 322 323 ## Common Patterns 324 325 ### Production Validation + Unmarshal 326 327 ```go 328 func ProcessData(schema *jsonschema.Schema, data []byte) (*User, error) { 329 // Step 1: Validate 330 result := schema.Validate(data) 331 if !result.IsValid() { 332 return nil, fmt.Errorf("validation failed: %v", result.Errors) 333 } 334 335 // Step 2: Unmarshal 336 var user User 337 if err := schema.Unmarshal(&user, data); err != nil { 338 return nil, fmt.Errorf("unmarshal failed: %w", err) 339 } 340 341 return &user, nil 342 } 343 ``` 344 345 ### Conditional Processing 346 347 ```go 348 func ProcessWithWarnings(schema *jsonschema.Schema, data []byte) (*User, []string) { 349 var warnings []string 350 351 // Always unmarshal (applies defaults) 352 var user User 353 schema.Unmarshal(&user, data) 354 355 // Check validation separately 356 result := schema.Validate(data) 357 if !result.IsValid() { 358 for field, err := range result.Errors { 359 warnings = append(warnings, fmt.Sprintf("%s: %s", field, err.Message)) 360 } 361 } 362 363 return &user, warnings 364 } 365 ``` 366 367 ### Localized Error Handling 368 369 ```go 370 func ValidateWithLocale(schema *jsonschema.Schema, data interface{}, locale string) error { 371 result := schema.Validate(data) 372 if result.IsValid() { 373 return nil 374 } 375 376 i18nBundle, _ := jsonschema.GetI18n() 377 localizer := i18nBundle.NewLocalizer(locale) 378 localizedList := result.ToLocalizeList(localizer) 379 380 var errors []string 381 for field, message := range localizedList.Errors { 382 errors = append(errors, fmt.Sprintf("%s: %s", field, message)) 383 } 384 385 return fmt.Errorf("validation failed: %s", strings.Join(errors, "; ")) 386 } 387 ``` 388