github.com/kaptinlin/jsonschema@v0.4.6/docs/validation.md (about) 1 # Validation Guide 2 3 Complete guide to validation methods and input types. 4 5 ## Validation Methods 6 7 ### Universal Method 8 9 #### schema.Validate(data interface{}) 10 11 Auto-detects input type and uses the optimal validation method. 12 13 ```go 14 // Works with any input type 15 result := schema.Validate(jsonBytes) // Detects JSON 16 result := schema.Validate(structData) // Detects struct 17 result := schema.Validate(mapData) // Detects map 18 ``` 19 20 **When to use:** Mixed input types or quick prototyping. 21 22 --- 23 24 ### Type-Specific Methods 25 26 Use these when you know your input type for best performance: 27 28 #### schema.ValidateJSON(data []byte) 29 30 Validates JSON byte arrays with optimized JSON parsing. 31 32 ```go 33 jsonData := []byte(`{"name": "John", "age": 30}`) 34 result := schema.ValidateJSON(jsonData) 35 36 if result.IsValid() { 37 fmt.Println("✅ Valid JSON") 38 } 39 ``` 40 41 **Performance benefits:** 42 - Single JSON parse operation 43 - No type detection overhead 44 - Direct JSON processing 45 46 --- 47 48 #### schema.ValidateStruct(data interface{}) 49 50 Validates Go structs directly using cached reflection. 51 52 ```go 53 type Person struct { 54 Name string `json:"name"` 55 Age int `json:"age"` 56 } 57 58 person := Person{Name: "John", Age: 30} 59 result := schema.ValidateStruct(person) 60 ``` 61 62 **Performance benefits:** 63 - Uses cached reflection data 64 - Zero-copy validation 65 - No JSON marshaling overhead 66 67 --- 68 69 #### schema.ValidateMap(data map[string]interface{}) 70 71 Validates map data optimally for pre-parsed JSON. 72 73 ```go 74 data := map[string]interface{}{ 75 "name": "John", 76 "age": 30, 77 } 78 result := schema.ValidateMap(data) 79 ``` 80 81 **Performance benefits:** 82 - Direct map processing 83 - No conversion overhead 84 - Optimal for pre-parsed JSON 85 86 --- 87 88 ## Input Types 89 90 ### JSON Bytes ([]byte) 91 92 The validator intelligently handles `[]byte` input: 93 94 ```go 95 // Valid JSON - parsed as JSON object/array 96 jsonBytes := []byte(`{"name": "John", "age": 25}`) 97 result := schema.Validate(jsonBytes) 98 99 // Invalid JSON starting with { or [ - returns parse error 100 malformedJSON := []byte(`{"name": "John", "age":`) 101 result := schema.Validate(malformedJSON) 102 103 // Binary data - treated as byte array 104 binaryBytes := []byte{1, 2, 3, 4, 5} 105 result := schema.Validate(binaryBytes) 106 ``` 107 108 ### Go Structs 109 110 Direct struct validation with JSON tag support: 111 112 ```go 113 type User struct { 114 Name string `json:"name"` 115 Age int `json:"age"` 116 Email string `json:"email,omitempty"` 117 Tags []string `json:"tags,omitempty"` 118 Created time.Time `json:"created_at"` 119 } 120 121 user := User{ 122 Name: "Alice", 123 Age: 28, 124 Email: "alice@example.com", 125 } 126 result := schema.ValidateStruct(user) 127 ``` 128 129 **Features:** 130 - Respects `json` tags (field renaming, `omitempty`) 131 - Handles nested structs 132 - Supports pointers and slices 133 - Time type support 134 135 ### Maps and Interfaces 136 137 Works with any map structure: 138 139 ```go 140 // Simple map 141 data := map[string]interface{}{ 142 "name": "Bob", 143 "age": 35, 144 } 145 146 // Nested map 147 nested := map[string]interface{}{ 148 "user": map[string]interface{}{ 149 "name": "Charlie", 150 "profile": map[string]interface{}{ 151 "bio": "Developer", 152 }, 153 }, 154 } 155 156 result := schema.ValidateMap(data) 157 result := schema.ValidateMap(nested) 158 ``` 159 160 --- 161 162 ## Working with Results 163 164 ### Basic Validation Check 165 166 ```go 167 result := schema.Validate(data) 168 169 if result.IsValid() { 170 fmt.Println("✅ Data is valid") 171 } else { 172 fmt.Println("❌ Validation failed") 173 } 174 ``` 175 176 ### Accessing Errors 177 178 ```go 179 result := schema.Validate(data) 180 181 if !result.IsValid() { 182 // Iterate through field errors 183 for field, err := range result.Errors { 184 fmt.Printf("Field '%s': %s\n", field, err.Message) 185 } 186 } 187 ``` 188 189 ### Different Output Formats 190 191 ```go 192 result := schema.Validate(data) 193 194 // Simple boolean flag 195 flag := result.ToFlag() 196 fmt.Printf("Valid: %t\n", flag.Valid) 197 198 // Structured list 199 list := result.ToList() 200 for field, message := range list.Errors { 201 fmt.Printf("%s: %s\n", field, message) 202 } 203 204 // Hierarchical structure (preserves nesting) 205 hierarchical := result.ToList(true) // includes hierarchy 206 flat := result.ToList(false) // flattened structure 207 ``` 208 209 --- 210 211 ## Performance Comparison 212 213 | Method | Input Type | Parse Cost | Type Detection | Best For | 214 |--------|------------|------------|----------------|----------| 215 | `Validate` | Any | Variable | Yes | Mixed types | 216 | `ValidateJSON` | `[]byte` | Once | No | JSON data | 217 | `ValidateStruct` | Struct | None | No | Go structs | 218 | `ValidateMap` | Map | None | No | Parsed JSON | 219 220 ## Method Selection Guide 221 222 **For JSON data:** 223 ```go 224 // Best performance for JSON 225 result := schema.ValidateJSON(jsonBytes) 226 ``` 227 228 **For Go structs:** 229 ```go 230 // Best performance for structs 231 result := schema.ValidateStruct(structData) 232 ``` 233 234 **For maps:** 235 ```go 236 // Best performance for maps 237 result := schema.ValidateMap(mapData) 238 ``` 239 240 **For mixed or unknown types:** 241 ```go 242 // Auto-detection with good performance 243 result := schema.Validate(anyData) 244 ``` 245 246 ## Error Handling Patterns 247 248 ### Simple Error Check 249 250 ```go 251 result := schema.Validate(data) 252 if !result.IsValid() { 253 return fmt.Errorf("validation failed") 254 } 255 ``` 256 257 ### Detailed Error Reporting 258 259 ```go 260 result := schema.Validate(data) 261 if !result.IsValid() { 262 var errorMessages []string 263 for field, err := range result.Errors { 264 errorMessages = append(errorMessages, 265 fmt.Sprintf("%s: %s", field, err.Message)) 266 } 267 return fmt.Errorf("validation errors: %s", 268 strings.Join(errorMessages, ", ")) 269 } 270 ``` 271 272 ### Custom Error Handling 273 274 ```go 275 result := schema.Validate(data) 276 if !result.IsValid() { 277 for field, err := range result.Errors { 278 switch err.Keyword { 279 case "required": 280 log.Printf("Missing required field: %s", field) 281 case "type": 282 log.Printf("Type mismatch for field: %s", field) 283 case "minimum": 284 log.Printf("Value too small for field: %s", field) 285 default: 286 log.Printf("Validation error for %s: %s", field, err.Message) 287 } 288 } 289 } 290 ```