Complete reference for all methods and types in the JSON Schema library.
Creates a new schema compiler with default settings.
compiler := jsonschema.NewCompiler()Compiles a JSON schema from bytes. Optionally provide an ID for schema referencing.
// Compile schema without ID
schema, err := compiler.Compile([]byte(`{"type": "string"}`))
// Compile schema with specific ID for referencing
schema, err := compiler.Compile([]byte(`{"type": "object", ...}`), "user.json")Registers a custom format validator.
compiler.RegisterFormat("uuid", func(value string) bool {
_, err := uuid.Parse(value)
return err == nil
})Removes a previously registered custom format from the compiler. If AssertFormat is
set to true, schemas that reference this format will fail validation; otherwise the
format annotation will be ignored.
// Remove a custom format
compiler.UnregisterFormat("uuid")Registers a function for dynamic default value generation.
// Register built-in function
compiler.RegisterDefaultFunc("now", jsonschema.DefaultNowFunc)
// Register custom function
compiler.RegisterDefaultFunc("uuid", func(args ...any) (any, error) {
return uuid.New().String(), nil
})
// Use in schema
schema := `{
"properties": {
"id": {"default": "uuid()"},
"timestamp": {"default": "now(2006-01-02)"}
}
}`Function signature: func(args ...any) (any, error)
- Functions should handle argument parsing gracefully
- Return values are used as defaults during unmarshaling
- Errors cause fallback to literal string values
Validates data against the schema. Auto-detects input type.
result := schema.Validate(data)
if result.IsValid() {
// Valid data
} else {
// Handle errors
for field, err := range result.Errors {
fmt.Printf("%s: %s\n", field, err.Message)
}
}Optimized validation for JSON bytes.
result := schema.ValidateJSON([]byte(`{"name": "John"}`))Zero-copy validation for Go structs.
user := User{Name: "John", Age: 25}
result := schema.ValidateStruct(user)Optimized validation for maps.
data := map[string]interface{}{"name": "John"}
result := schema.ValidateMap(data)Important: Unmarshal methods do NOT perform validation. Always validate separately.
Unmarshals data into destination, applying default values from schema.
// Recommended workflow
result := schema.Validate(data)
if result.IsValid() {
var user User
err := schema.Unmarshal(&user, data)
if err != nil {
// Handle unmarshal error
}
} else {
// Handle validation errors
}Supported source types:
[]byte(JSON data)map[string]interface{}(parsed JSON object)- Go structs and other types
Supported destination types:
*struct(Go struct pointer)*map[string]interface{}(map pointer)- Other pointer types
Sets a custom compiler for the schema and returns the schema for method chaining.
// Create custom compiler with functions
compiler := jsonschema.NewCompiler()
compiler.RegisterDefaultFunc("now", jsonschema.DefaultNowFunc)
compiler.RegisterDefaultFunc("uuid", generateUUID)
// Set compiler on schema
schema := jsonschema.Object(
jsonschema.Prop("id", jsonschema.String(jsonschema.Default("uuid()"))),
jsonschema.Prop("timestamp", jsonschema.String(jsonschema.Default("now()"))),
).SetCompiler(compiler)
// Child schemas automatically inherit parent's compilerReturns the effective compiler for the schema with smart inheritance.
compiler := schema.Compiler()
// Inheritance order:
// 1. Current schema's compiler
// 2. Parent schema's compiler (recursive)
// 3. Default global compilerUse cases:
- Per-schema functions: Isolate function registries for different schemas
- Function inheritance: Child schemas automatically use parent's compiler
- Dynamic defaults: Enable function-based default value generation
Returns true if validation passed.
if result.IsValid() {
// Process valid data
}Map of validation errors by field path.
for field, err := range result.Errors {
switch err.Keyword {
case "required":
fmt.Printf("Missing: %s\n", field)
case "type":
fmt.Printf("Wrong type: %s\n", field)
default:
fmt.Printf("%s: %s\n", field, err.Message)
}
}Converts result to a flat list format.
list := result.ToList()
for field, message := range list.Errors {
fmt.Printf("%s: %s\n", field, message)
}Converts result with localized error messages.
zh, _ := i18n.New("zh-Hans") // import "github.com/kaptinlin/jsonschema/i18n"
list := result.ToLocalizedList(zh)⭐ Recommended for most users - Collects all detailed validation errors from the nested Details hierarchy. Returns a flattened map where keys are field paths and values are specific English error messages. This method helps access validation failures that might be buried in nested structures.
result := schema.Validate(data)
if !result.IsValid() {
detailedErrors := result.DetailedErrors()
for path, message := range detailedErrors {
fmt.Printf("Field '%s': %s\n", path, message)
}
}Same as DetailedErrors, rendered through a Translator. Missing translations fall back to the built-in English message.
zh, _ := i18n.New("zh-Hans") // import "github.com/kaptinlin/jsonschema/i18n"
detailedErrors := result.LocalizedDetailedErrors(zh)
for path, message := range detailedErrors {
fmt.Printf("字段 '%s': %s\n", path, message) // Chinese messages
}Why use DetailedErrors instead of result.Errors?
result.Errors: Generic messages like "Property 'jobs' does not match the schema" ❌DetailedErrors(): Specific messages like "Required property 'runs-on' is missing" ✅
Validation error with detailed information.
Keyword string- JSON Schema keyword that failedCode string- Error code for i18nMessage string- Human-readable error messageParams map[string]interface{}- Parameters for templating
Returns localized error message.
Error during unmarshaling process.
Type string- Error category ("destination", "source", "defaults", "unmarshal")Field string- Field that caused the error (if applicable)Reason string- Human-readable reasonErr error- Wrapped underlying error
var unmarshalErr *jsonschema.UnmarshalError
if errors.As(err, &unmarshalErr) {
switch unmarshalErr.Type {
case "destination":
// Invalid destination (nil, not pointer, etc.)
case "source":
// Invalid source data
case "defaults":
// Error applying default values
case "unmarshal":
// Error during unmarshaling
}
}The root package has zero translation-framework dependencies; pure validation users pay no Intl compile, link, or binary cost. Localization is opt-in via the Translator interface and the i18n subpackage.
The consumer-side interface the root package renders localized messages through. Implement it with any backend — a database, gettext, or a hardcoded map.
type Translator interface {
Translate(code string, params map[string]any) (message string, ok bool)
}Return ok=false when no translation exists; callers fall back to the built-in English message.
Creates a translator bound to one locale, backed by the built-in catalogs. Unknown locales are an error here rather than a silent fall back to English.
import "github.com/kaptinlin/jsonschema/i18n"
zh, err := i18n.New("zh-Hans")
if err != nil {
log.Fatal(err)
}Supported locales:
en- Englishzh-Hans- Simplified Chinesezh-Hant- Traditional Chineseja-JP- Japaneseko-KR- Koreanfr-FR- Frenchde-DE- Germanes-ES- Spanishpt-BR- Portuguese (Brazil)
func ProcessData(schema *jsonschema.Schema, data []byte) (*User, error) {
// Step 1: Validate
result := schema.Validate(data)
if !result.IsValid() {
return nil, fmt.Errorf("validation failed: %v", result.Errors)
}
// Step 2: Unmarshal
var user User
if err := schema.Unmarshal(&user, data); err != nil {
return nil, fmt.Errorf("unmarshal failed: %w", err)
}
return &user, nil
}func ProcessWithWarnings(schema *jsonschema.Schema, data []byte) (*User, []string) {
var warnings []string
// Always unmarshal (applies defaults)
var user User
schema.Unmarshal(&user, data)
// Check validation separately
result := schema.Validate(data)
if !result.IsValid() {
for field, err := range result.Errors {
warnings = append(warnings, fmt.Sprintf("%s: %s", field, err.Message))
}
}
return &user, warnings
}func ValidateWithLocale(schema *jsonschema.Schema, data interface{}, locale string) error {
result := schema.Validate(data)
if result.IsValid() {
return nil
}
translator, err := i18n.New(locale) // import "github.com/kaptinlin/jsonschema/i18n"
if err != nil {
return err
}
localizedList := result.ToLocalizedList(translator)
var errors []string
for field, message := range localizedList.Errors {
errors = append(errors, fmt.Sprintf("%s: %s", field, message))
}
return fmt.Errorf("validation failed: %s", strings.Join(errors, "; "))
}