github.com/kaptinlin/jsonschema@v0.4.6/docs/constructor.md (about) 1 # JSON Schema Constructor API 2 3 The Constructor API provides a type-safe way to build JSON Schema using Go code. It supports all JSON Schema 2020-12 keywords and enables validation without compilation. 4 5 ## Table of Contents 6 7 - [Quick Start](#quick-start) 8 - [Basic Usage](#basic-usage) 9 - [Core Types](#core-types) 10 - [Validation Keywords](#validation-keywords) 11 - [Advanced Patterns](#advanced-patterns) 12 - [Convenience Functions](#convenience-functions) 13 - [API Reference](#api-reference) 14 15 ## Quick Start 16 17 ```go 18 import "github.com/kaptinlin/jsonschema" 19 20 // Create a user schema 21 userSchema := jsonschema.Object( 22 jsonschema.Prop("name", jsonschema.String(jsonschema.MinLen(1))), 23 jsonschema.Prop("age", jsonschema.Integer(jsonschema.Min(0))), 24 jsonschema.Prop("email", jsonschema.Email()), 25 jsonschema.Required("name", "email"), 26 ) 27 28 // Validate data - no compilation step required 29 data := map[string]interface{}{ 30 "name": "John Doe", 31 "age": 30, 32 "email": "john@example.com", 33 } 34 35 result := userSchema.Validate(data) 36 if result.IsValid() { 37 fmt.Println("✅ Valid") 38 } else { 39 for field, err := range result.Errors { 40 fmt.Printf("❌ %s: %s\n", field, err.Message) 41 } 42 } 43 ``` 44 45 ## Basic Usage 46 47 ### Building Schemas 48 49 The Constructor API uses function composition to build schemas: 50 51 ```go 52 // String with validation 53 nameSchema := jsonschema.String( 54 jsonschema.MinLen(1), 55 jsonschema.MaxLen(100), 56 jsonschema.Pattern("^[a-zA-Z\\s]+$"), 57 ) 58 59 // Integer with constraints 60 ageSchema := jsonschema.Integer( 61 jsonschema.Min(0), 62 jsonschema.Max(150), 63 ) 64 65 // Array of strings 66 tagsSchema := jsonschema.Array( 67 jsonschema.Items(jsonschema.String()), 68 jsonschema.MinItems(1), 69 jsonschema.UniqueItems(true), 70 ) 71 ``` 72 73 ### Object Schemas 74 75 Objects are constructed using properties and keywords: 76 77 ```go 78 profileSchema := jsonschema.Object( 79 // Properties 80 jsonschema.Prop("username", jsonschema.String( 81 jsonschema.MinLen(3), 82 jsonschema.Pattern("^[a-zA-Z0-9_]+$"), 83 )), 84 jsonschema.Prop("profile", jsonschema.Object( 85 jsonschema.Prop("firstName", jsonschema.String()), 86 jsonschema.Prop("lastName", jsonschema.String()), 87 )), 88 jsonschema.Prop("settings", jsonschema.Object( 89 jsonschema.Prop("theme", jsonschema.Enum("light", "dark", "auto")), 90 jsonschema.Prop("notifications", jsonschema.Boolean()), 91 )), 92 93 // Object constraints 94 jsonschema.Required("username"), 95 jsonschema.AdditionalProps(false), 96 ) 97 ``` 98 99 ## Core Types 100 101 ### Basic Types 102 103 ```go 104 // String schema 105 jsonschema.String(keywords...) // String with validation keywords 106 jsonschema.Integer(keywords...) // Integer with constraints 107 jsonschema.Number(keywords...) // Number with constraints 108 jsonschema.Boolean() // Boolean type 109 jsonschema.Null() // Null type 110 jsonschema.Array(keywords...) // Array with validation 111 jsonschema.Object(props...) // Object with properties 112 jsonschema.Any() // Any type (no restrictions) 113 ``` 114 115 ### Value Constraints 116 117 ```go 118 // Constant values 119 jsonschema.Const("fixed-value") // Exact value match 120 jsonschema.Enum("red", "green", "blue") // One of specified values 121 ``` 122 123 ### Schema Composition 124 125 ```go 126 // Logical combinations 127 jsonschema.OneOf(schemas...) // Exactly one schema must match 128 jsonschema.AnyOf(schemas...) // At least one schema must match 129 jsonschema.AllOf(schemas...) // All schemas must match 130 jsonschema.Not(schema) // Schema must not match 131 ``` 132 133 ### References 134 135 ```go 136 // Schema references 137 jsonschema.Ref("#/definitions/User") // Reference to another schema 138 ``` 139 140 ## Validation Keywords 141 142 ### String Keywords 143 144 ```go 145 jsonschema.String( 146 jsonschema.MinLen(5), // Minimum length 147 jsonschema.MaxLen(100), // Maximum length 148 jsonschema.Pattern("^[a-zA-Z]+$"), // Regular expression 149 jsonschema.Format("email"), // Format validation 150 ) 151 ``` 152 153 ### Number Keywords 154 155 ```go 156 jsonschema.Number( 157 jsonschema.Min(0), // Minimum value (inclusive) 158 jsonschema.Max(100), // Maximum value (inclusive) 159 jsonschema.ExclusiveMin(0), // Minimum value (exclusive) 160 jsonschema.ExclusiveMax(100), // Maximum value (exclusive) 161 jsonschema.MultipleOf(2.5), // Must be multiple of value 162 ) 163 ``` 164 165 ### Array Keywords 166 167 ```go 168 jsonschema.Array( 169 jsonschema.Items(itemSchema), // Schema for array items 170 jsonschema.MinItems(1), // Minimum number of items 171 jsonschema.MaxItems(10), // Maximum number of items 172 jsonschema.UniqueItems(true), // Items must be unique 173 jsonschema.Contains(schema), // Array must contain item matching schema 174 jsonschema.MinContains(2), // Minimum matching contains items 175 jsonschema.MaxContains(5), // Maximum matching contains items 176 jsonschema.PrefixItems(schemas...), // Schemas for array prefix 177 jsonschema.UnevaluatedItems(schema), // Schema for unevaluated items 178 ) 179 ``` 180 181 ### Object Keywords 182 183 ```go 184 jsonschema.Object( 185 // Property constraints 186 jsonschema.Required("field1", "field2"), // Required properties 187 jsonschema.MinProps(1), // Minimum number of properties 188 jsonschema.MaxProps(10), // Maximum number of properties 189 190 // Additional properties 191 jsonschema.AdditionalProps(false), // Disallow additional properties 192 jsonschema.AdditionalPropsSchema(schema), // Schema for additional properties 193 194 // Pattern properties 195 jsonschema.PatternProps(map[string]*Schema{ 196 "^str_": jsonschema.String(), 197 "^num_": jsonschema.Number(), 198 }), 199 200 // Property names 201 jsonschema.PropertyNames( 202 jsonschema.String(jsonschema.Pattern("^[a-zA-Z_]+$")), 203 ), 204 205 // Dependencies 206 jsonschema.DependentRequired(map[string][]string{ 207 "credit_card": {"billing_address"}, 208 }), 209 jsonschema.DependentSchemas(map[string]*Schema{ 210 "credit_card": jsonschema.Object( 211 jsonschema.Required("billing_address"), 212 ), 213 }), 214 215 // Unevaluated properties 216 jsonschema.UnevaluatedProps(schema), 217 ) 218 ``` 219 220 ### Annotation Keywords 221 222 ```go 223 // Metadata (doesn't affect validation) 224 jsonschema.String( 225 jsonschema.Title("User Name"), // Human-readable title 226 jsonschema.Description("User's login name"), // Detailed description 227 jsonschema.Default("guest"), // Default value 228 jsonschema.Examples("admin", "user"), // Example values 229 jsonschema.Deprecated(true), // Mark as deprecated 230 jsonschema.ReadOnly(true), // Read-only field 231 jsonschema.WriteOnly(true), // Write-only field 232 ) 233 ``` 234 235 ## Advanced Patterns 236 237 ### Schema Registration 238 239 The Constructor API integrates with the compiler system for schema registration and reuse: 240 241 #### Direct Registration 242 243 ```go 244 // Create a reusable schema with ID 245 userSchema := jsonschema.Object( 246 jsonschema.ID("https://example.com/schemas/user"), 247 jsonschema.Prop("id", jsonschema.UUID()), 248 jsonschema.Prop("name", jsonschema.String(jsonschema.MinLen(1))), 249 jsonschema.Prop("email", jsonschema.Email()), 250 jsonschema.Required("id", "name", "email"), 251 ) 252 253 // Register schema with compiler 254 compiler := jsonschema.NewCompiler() 255 compiler.SetSchema("https://example.com/schemas/user", userSchema) 256 ``` 257 258 #### Using Registered Schemas 259 260 ```go 261 // Reference registered schema in JSON 262 profileJSON := `{ 263 "type": "object", 264 "properties": { 265 "user": {"$ref": "https://example.com/schemas/user"}, 266 "bio": {"type": "string"}, 267 "lastLogin": {"type": "string", "format": "date-time"} 268 }, 269 "required": ["user"] 270 }` 271 272 // Compile schema that references registered constructor schema 273 profileSchema, err := compiler.Compile([]byte(profileJSON)) 274 if err != nil { 275 log.Fatal(err) 276 } 277 278 // Validate data against composed schema 279 data := map[string]interface{}{ 280 "user": map[string]interface{}{ 281 "id": "550e8400-e29b-41d4-a716-446655440000", 282 "name": "Alice", 283 "email": "alice@example.com", 284 }, 285 "bio": "Software Developer", 286 "lastLogin": "2023-12-01T10:30:00Z", 287 } 288 289 result := profileSchema.Validate(data) 290 ``` 291 292 #### Schema Definitions with $defs 293 294 ```go 295 // Schema with internal definitions 296 apiSchema := jsonschema.Object( 297 jsonschema.Prop("users", jsonschema.Array( 298 jsonschema.Items(jsonschema.Ref("#/$defs/User")), 299 )), 300 jsonschema.Prop("pagination", jsonschema.Ref("#/$defs/Pagination")), 301 jsonschema.Defs(map[string]*Schema{ 302 "User": jsonschema.Object( 303 jsonschema.Prop("id", jsonschema.UUID()), 304 jsonschema.Prop("name", jsonschema.String()), 305 jsonschema.Required("id", "name"), 306 ), 307 "Pagination": jsonschema.Object( 308 jsonschema.Prop("page", jsonschema.PositiveInt()), 309 jsonschema.Prop("size", jsonschema.Integer( 310 jsonschema.Min(1), 311 jsonschema.Max(100), 312 )), 313 jsonschema.Prop("total", jsonschema.NonNegativeInt()), 314 jsonschema.Required("page", "size", "total"), 315 ), 316 }), 317 jsonschema.Required("users", "pagination"), 318 ) 319 ``` 320 321 ### Conditional Schemas 322 323 Use If/Then/Else for conditional validation: 324 325 ```go 326 // If user type is "premium", then premium features are required 327 conditionalSchema := jsonschema.If( 328 jsonschema.Object( 329 jsonschema.Prop("type", jsonschema.Const("premium")), 330 ), 331 ).Then( 332 jsonschema.Object( 333 jsonschema.Required("premium_features"), 334 ), 335 ).Else( 336 jsonschema.Object( 337 jsonschema.Prop("premium_features", jsonschema.Not(jsonschema.Any())), 338 ), 339 ) 340 ``` 341 342 ### Complex Nested Structures 343 344 ```go 345 blogPostSchema := jsonschema.Object( 346 jsonschema.Prop("id", jsonschema.UUID()), 347 jsonschema.Prop("title", jsonschema.String( 348 jsonschema.MinLen(1), 349 jsonschema.MaxLen(200), 350 )), 351 jsonschema.Prop("author", jsonschema.Object( 352 jsonschema.Prop("id", jsonschema.UUID()), 353 jsonschema.Prop("name", jsonschema.String()), 354 jsonschema.Prop("email", jsonschema.Email()), 355 jsonschema.Required("id", "name", "email"), 356 )), 357 jsonschema.Prop("tags", jsonschema.Array( 358 jsonschema.Items(jsonschema.String( 359 jsonschema.MinLen(1), 360 jsonschema.MaxLen(50), 361 )), 362 jsonschema.UniqueItems(true), 363 jsonschema.MinItems(1), 364 jsonschema.MaxItems(10), 365 )), 366 jsonschema.Prop("comments", jsonschema.Array( 367 jsonschema.Items(jsonschema.Object( 368 jsonschema.Prop("id", jsonschema.UUID()), 369 jsonschema.Prop("content", jsonschema.String(jsonschema.MinLen(1))), 370 jsonschema.Prop("author_name", jsonschema.String()), 371 jsonschema.Prop("created_at", jsonschema.DateTime()), 372 jsonschema.Required("id", "content", "author_name", "created_at"), 373 )), 374 )), 375 jsonschema.Required("id", "title", "author", "tags"), 376 ) 377 ``` 378 379 ### Schema Composition Examples 380 381 ```go 382 // OneOf: User can authenticate with email OR username 383 authSchema := jsonschema.OneOf( 384 jsonschema.Object( 385 jsonschema.Prop("email", jsonschema.Email()), 386 jsonschema.Prop("password", jsonschema.String()), 387 jsonschema.Required("email", "password"), 388 jsonschema.AdditionalProps(false), 389 ), 390 jsonschema.Object( 391 jsonschema.Prop("username", jsonschema.String()), 392 jsonschema.Prop("password", jsonschema.String()), 393 jsonschema.Required("username", "password"), 394 jsonschema.AdditionalProps(false), 395 ), 396 ) 397 398 // AnyOf: Contact info can be email, phone, or both 399 contactSchema := jsonschema.AnyOf( 400 jsonschema.Object( 401 jsonschema.Prop("email", jsonschema.Email()), 402 jsonschema.Required("email"), 403 ), 404 jsonschema.Object( 405 jsonschema.Prop("phone", jsonschema.String()), 406 jsonschema.Required("phone"), 407 ), 408 ) 409 410 // AllOf: Combine multiple constraints 411 strictUserSchema := jsonschema.AllOf( 412 jsonschema.Object( 413 jsonschema.Prop("name", jsonschema.String()), 414 jsonschema.Required("name"), 415 ), 416 jsonschema.Object( 417 jsonschema.MinProps(1), 418 jsonschema.MaxProps(10), 419 ), 420 ) 421 ``` 422 423 ## Convenience Functions 424 425 Predefined schemas for common formats and patterns: 426 427 ### Format Functions 428 429 ```go 430 // String formats 431 jsonschema.Email() // Email format 432 jsonschema.DateTime() // ISO 8601 date-time 433 jsonschema.Date() // ISO 8601 date 434 jsonschema.Time() // ISO 8601 time 435 jsonschema.URI() // URI format 436 jsonschema.URIRef() // URI reference 437 jsonschema.UUID() // UUID format 438 jsonschema.Hostname() // Hostname format 439 jsonschema.IPv4() // IPv4 address 440 jsonschema.IPv6() // IPv6 address 441 jsonschema.IdnEmail() // Internationalized email 442 jsonschema.IdnHostname() // Internationalized hostname 443 jsonschema.IRI() // IRI format 444 jsonschema.IRIRef() // IRI reference 445 jsonschema.URITemplate() // URI template 446 jsonschema.JSONPointer() // JSON Pointer 447 jsonschema.RelativeJSONPointer() // Relative JSON Pointer 448 jsonschema.Duration() // Duration format 449 jsonschema.Regex() // Regular expression 450 ``` 451 452 ### Number Functions 453 454 ```go 455 // Integer constraints 456 jsonschema.PositiveInt() // minimum: 1 457 jsonschema.NonNegativeInt() // minimum: 0 458 jsonschema.NegativeInt() // maximum: -1 459 jsonschema.NonPositiveInt() // maximum: 0 460 ``` 461 462 ### Usage Example 463 464 ```go 465 apiSchema := jsonschema.Object( 466 jsonschema.Prop("id", jsonschema.UUID()), 467 jsonschema.Prop("created_at", jsonschema.DateTime()), 468 jsonschema.Prop("website", jsonschema.URI()), 469 jsonschema.Prop("email", jsonschema.Email()), 470 jsonschema.Prop("count", jsonschema.NonNegativeInt()), 471 jsonschema.Prop("score", jsonschema.PositiveInt()), 472 ) 473 ``` 474 475 ## API Reference 476 477 ### Core Constructor Functions 478 479 #### Object(items ...interface{}) *Schema 480 Creates an object schema. Accepts properties and object keywords. 481 482 ```go 483 schema := jsonschema.Object( 484 jsonschema.Prop("name", jsonschema.String()), 485 jsonschema.Required("name"), 486 ) 487 ``` 488 489 #### String(keywords ...Keyword) *Schema 490 Creates a string schema with validation keywords. 491 492 ```go 493 schema := jsonschema.String( 494 jsonschema.MinLen(1), 495 jsonschema.Format("email"), 496 ) 497 ``` 498 499 #### Integer(keywords ...Keyword) *Schema 500 Creates an integer schema with number keywords. 501 502 ```go 503 schema := jsonschema.Integer( 504 jsonschema.Min(0), 505 jsonschema.Max(100), 506 ) 507 ``` 508 509 #### Number(keywords ...Keyword) *Schema 510 Creates a number schema with number keywords. 511 512 ```go 513 schema := jsonschema.Number( 514 jsonschema.Min(0.0), 515 jsonschema.MultipleOf(0.5), 516 ) 517 ``` 518 519 #### Boolean(keywords ...Keyword) *Schema 520 Creates a boolean schema. 521 522 ```go 523 schema := jsonschema.Boolean() 524 ``` 525 526 #### Null(keywords ...Keyword) *Schema 527 Creates a null schema. 528 529 ```go 530 schema := jsonschema.Null() 531 ``` 532 533 #### Array(keywords ...Keyword) *Schema 534 Creates an array schema with array keywords. 535 536 ```go 537 schema := jsonschema.Array( 538 jsonschema.Items(jsonschema.String()), 539 jsonschema.MinItems(1), 540 ) 541 ``` 542 543 #### Any(keywords ...Keyword) *Schema 544 Creates a schema that accepts any type. 545 546 ```go 547 schema := jsonschema.Any() 548 ``` 549 550 ### Property Definition 551 552 #### Prop(name string, schema *Schema) Property 553 Creates a property definition for objects. 554 555 ```go 556 prop := jsonschema.Prop("username", jsonschema.String()) 557 ``` 558 559 ### Schema Composition 560 561 #### Const(value interface{}) *Schema 562 Creates a constant value schema. 563 564 ```go 565 schema := jsonschema.Const("fixed-value") 566 ``` 567 568 #### Enum(values ...interface{}) *Schema 569 Creates an enumeration schema. 570 571 ```go 572 schema := jsonschema.Enum("red", "green", "blue") 573 ``` 574 575 #### OneOf(schemas ...*Schema) *Schema 576 Creates a oneOf composition schema. 577 578 ```go 579 schema := jsonschema.OneOf( 580 jsonschema.String(), 581 jsonschema.Integer(), 582 ) 583 ``` 584 585 #### AnyOf(schemas ...*Schema) *Schema 586 Creates an anyOf composition schema. 587 588 ```go 589 schema := jsonschema.AnyOf( 590 jsonschema.String(jsonschema.MinLen(5)), 591 jsonschema.Integer(jsonschema.Min(0)), 592 ) 593 ``` 594 595 #### AllOf(schemas ...*Schema) *Schema 596 Creates an allOf composition schema. 597 598 ```go 599 schema := jsonschema.AllOf( 600 jsonschema.Object(jsonschema.Prop("name", jsonschema.String())), 601 jsonschema.Object(jsonschema.MinProps(1)), 602 ) 603 ``` 604 605 #### Not(schema *Schema) *Schema 606 Creates a negation schema. 607 608 ```go 609 schema := jsonschema.Not(jsonschema.String()) 610 ``` 611 612 #### Ref(reference string) *Schema 613 Creates a reference schema. 614 615 ```go 616 schema := jsonschema.Ref("#/definitions/User") 617 ``` 618 619 ### Conditional Logic 620 621 #### If(condition *Schema) *ConditionalSchema 622 Creates a conditional schema. 623 624 ```go 625 conditionalSchema := jsonschema.If( 626 jsonschema.Object( 627 jsonschema.Prop("type", jsonschema.Const("premium")), 628 ), 629 ).Then( 630 jsonschema.Object( 631 jsonschema.Required("premium_features"), 632 ), 633 ).Else( 634 jsonschema.Object( 635 jsonschema.Required("basic_features"), 636 ), 637 ) 638 ``` 639 640 ## Keyword Reference 641 642 ### String Keywords 643 644 - `MinLen(min int) Keyword` - Sets minLength 645 - `MaxLen(max int) Keyword` - Sets maxLength 646 - `Pattern(pattern string) Keyword` - Sets pattern 647 - `Format(format string) Keyword` - Sets format 648 649 ### Number Keywords 650 651 - `Min(min float64) Keyword` - Sets minimum 652 - `Max(max float64) Keyword` - Sets maximum 653 - `ExclusiveMin(min float64) Keyword` - Sets exclusiveMinimum 654 - `ExclusiveMax(max float64) Keyword` - Sets exclusiveMaximum 655 - `MultipleOf(multiple float64) Keyword` - Sets multipleOf 656 657 ### Array Keywords 658 659 - `Items(schema *Schema) Keyword` - Sets items 660 - `MinItems(min int) Keyword` - Sets minItems 661 - `MaxItems(max int) Keyword` - Sets maxItems 662 - `UniqueItems(unique bool) Keyword` - Sets uniqueItems 663 - `Contains(schema *Schema) Keyword` - Sets contains 664 - `MinContains(min int) Keyword` - Sets minContains 665 - `MaxContains(max int) Keyword` - Sets maxContains 666 - `PrefixItems(schemas ...*Schema) Keyword` - Sets prefixItems 667 - `UnevaluatedItems(schema *Schema) Keyword` - Sets unevaluatedItems 668 669 ### Object Keywords 670 671 - `Required(fields ...string) Keyword` - Sets required 672 - `AdditionalProps(allowed bool) Keyword` - Sets additionalProperties (boolean) 673 - `AdditionalPropsSchema(schema *Schema) Keyword` - Sets additionalProperties (schema) 674 - `MinProps(min int) Keyword` - Sets minProperties 675 - `MaxProps(max int) Keyword` - Sets maxProperties 676 - `PatternProps(patterns map[string]*Schema) Keyword` - Sets patternProperties 677 - `PropertyNames(schema *Schema) Keyword` - Sets propertyNames 678 - `UnevaluatedProps(schema *Schema) Keyword` - Sets unevaluatedProperties 679 - `DependentRequired(dependencies map[string][]string) Keyword` - Sets dependentRequired 680 - `DependentSchemas(dependencies map[string]*Schema) Keyword` - Sets dependentSchemas 681 682 ### Annotation Keywords 683 684 - `Title(title string) Keyword` - Sets title 685 - `Description(desc string) Keyword` - Sets description 686 - `Default(value interface{}) Keyword` - Sets default 687 - `Examples(examples ...interface{}) Keyword` - Sets examples 688 - `Deprecated(deprecated bool) Keyword` - Sets deprecated 689 - `ReadOnly(readOnly bool) Keyword` - Sets readOnly 690 - `WriteOnly(writeOnly bool) Keyword` - Sets writeOnly 691 692 ### Content Keywords 693 694 - `ContentEncoding(encoding string) Keyword` - Sets contentEncoding 695 - `ContentMediaType(mediaType string) Keyword` - Sets contentMediaType 696 - `ContentSchema(schema *Schema) Keyword` - Sets contentSchema 697 698 ### Core Identifier Keywords 699 700 - `ID(id string) Keyword` - Sets $id 701 - `SchemaURI(schemaURI string) Keyword` - Sets $schema 702 - `Anchor(anchor string) Keyword` - Sets $anchor 703 - `DynamicAnchor(anchor string) Keyword` - Sets $dynamicAnchor 704 - `Defs(defs map[string]*Schema) Keyword` - Sets $defs 705 706 ## Format Constants 707 708 ```go 709 const ( 710 FormatEmail = "email" 711 FormatDateTime = "date-time" 712 FormatDate = "date" 713 FormatTime = "time" 714 FormatURI = "uri" 715 FormatURIRef = "uri-reference" 716 FormatUUID = "uuid" 717 FormatHostname = "hostname" 718 FormatIPv4 = "ipv4" 719 FormatIPv6 = "ipv6" 720 FormatRegex = "regex" 721 FormatIdnEmail = "idn-email" 722 FormatIdnHostname = "idn-hostname" 723 FormatIRI = "iri" 724 FormatIRIRef = "iri-reference" 725 FormatURITemplate = "uri-template" 726 FormatJSONPointer = "json-pointer" 727 FormatRelativeJSONPointer = "relative-json-pointer" 728 FormatDuration = "duration" 729 ) 730 ``` 731 732 ## Benefits 733 734 The Constructor API offers several characteristics compared to JSON string compilation: 735 736 1. **Type Safety**: Compile-time checking prevents invalid keyword usage 737 2. **Direct Use**: Schemas can be used without parsing step 738 3. **Composability**: Supports building complex schemas from reusable components 739 4. **Code Structure**: Schema structure corresponds to code structure 740 5. **Maintainability**: Changes and refactoring can be handled through IDE tools 741 6. **Specification Coverage**: Supports all JSON Schema 2020-12 keywords 742 743 ## Compatibility 744 745 The Constructor API works alongside the existing JSON compilation API: 746 747 ```go 748 // Constructor API 749 constructedSchema := jsonschema.Object( 750 jsonschema.Prop("name", jsonschema.String()), 751 ) 752 753 // JSON compilation API 754 compiler := jsonschema.NewCompiler() 755 jsonSchema, _ := compiler.Compile([]byte(`{ 756 "type": "object", 757 "properties": { 758 "name": {"type": "string"} 759 } 760 }`)) 761 762 // Both schemas function identically 763 data := map[string]interface{}{"name": "test"} 764 result1 := constructedSchema.Validate(data) 765 result2 := jsonSchema.Validate(data) 766 ``` 767 768 This compatibility enables adoption and allows using both approaches in the same application.