A powerful, fluent Go library for schema validation and JSON Schema generation with internationalization support.
- Fluent API: Chainable method calls for intuitive schema construction
- Type Safety: Strong typing with validation for primitives, objects, arrays, and unions
- JSON Schema Generation: Export schemas as standard JSON Schema format
- Internationalization: Built-in i18n support for error messages
- Comprehensive Validation: Support for all common validation constraints
- Advanced Schema Types: AllOf, AnyOf, OneOf, Not, and conditional schemas
- Format Validation: Built-in support for email, URI, UUID, date-time, and more
- Custom Error Messages: Override default validation messages with custom ones
- Nullable & Optional: Fine-grained control over required fields and null values
go get github.com/nyxstack/schema
For comprehensive documentation on all schema types, including detailed examples and API references:
π View Full Documentation β
Quick links to specific schema types:
- String Schema - Text validation with formats and patterns
- Int/Number Schema - Integer and floating-point validation
- Object Schema - Structured data validation
- Array Schema - Collection validation
- Union Schema - Multiple schema options (OneOf/AnyOf/AllOf)
- Conditional Schema - If/then/else validation logic
- UUID Schema - UUID validation with versions
- Date Schema - Date, DateTime, Time validation
- Transform Schema - Input transformation and validation
- Ref Schema - Schema references and reuse
package main import ( "fmt" "github.com/nyxstack/schema" ) func main() { // Create a string schema with validation nameSchema := schema.String(). Title("Full Name"). Description("User's full name"). MinLength(2). MaxLength(50). Pattern("^[a-zA-Z\\s]+$"). Required() // Validate data ctx := schema.DefaultValidationContext() result := nameSchema.Parse("John Doe", ctx) if result.Valid { fmt.Printf("Valid name: %v\n", result.Value) } else { for _, err := range result.Errors { fmt.Printf("Error: %s\n", err.Message) } } }
// Basic string validation emailSchema := schema.String(). Email(). Required("Email is required"). MinLength(5, "Email too short") // Pattern validation usernameSchema := schema.String(). Pattern("^[a-zA-Z0-9_]+$"). MinLength(3). MaxLength(20) // Enum validation statusSchema := schema.String(). Enum([]string{"active", "inactive", "pending"})
// Integer validation ageSchema := schema.Int(). Min(0). Max(120). Required() // Float validation priceSchema := schema.Float(). Min(0.01). Max(9999.99). MultipleOf(0.01)
// Array of strings tagsSchema := schema.Array(schema.String().MinLength(1)). MinItems(1). MaxItems(10). UniqueItems() // Complex array validation usersSchema := schema.Array( schema.Object(). Property("name", schema.String().Required()). Property("email", schema.String().Email().Required()), ).MinItems(1)
// Structured object validation userSchema := schema.Object(). Property("id", schema.Int().Min(1).Required()). Property("name", schema.String().MinLength(2).Required()). Property("email", schema.String().Email().Required()). Property("age", schema.Int().Min(13).Max(120).Optional()). Property("tags", schema.Array(schema.String()).Optional()). AdditionalProperties(false) // Using Shape for concise object creation user := schema.Shape{ "name": schema.String().Required(), "email": schema.String().Email().Required(), "age": schema.Int().Min(0).Optional(), }.AsObject()
// Record schema for key-value maps with dynamic keys metadataSchema := schema.Record( schema.String().MinLength(1), // Key schema schema.String().MinLength(1), // Value schema ).MinProperties(1).MaxProperties(10) // Example: validate a map of string labels labelsSchema := schema.Record( schema.String().Pattern("^[a-z0-9-]+$"), // Keys must be lowercase with dashes schema.String().MaxLength(100), // Values max 100 chars )
// AnyOf - value matches at least one schema stringOrNumber := schema.AnyOf( schema.String().MinLength(1), schema.Int().Min(0), ) // OneOf - value matches exactly one schema idSchema := schema.OneOf( schema.String().Pattern("^[a-zA-Z0-9_]+$"), schema.Int().Min(1), ) // AllOf - value matches all schemas restrictiveString := schema.AllOf( schema.String().MinLength(8), schema.String().Pattern(".*[A-Z].*"), schema.String().Pattern(".*[0-9].*"), )
conditionalSchema := schema.Conditional(). If(schema.Object().Property("type", schema.String().Const("premium"))). Then(schema.Object().Property("features", schema.Array(schema.String()).MinItems(3))). Else(schema.Object().Property("features", schema.Array(schema.String()).MaxItems(1)))
schema := schema.String(). MinLength(8, "Password must be at least 8 characters"). Pattern(".*[A-Z].*", "Password must contain uppercase letter"). Required("Password is mandatory")
// Optional field (can be omitted) optionalField := schema.String().Optional() // Nullable field (can be null) nullableField := schema.String().Nullable() // Both optional and nullable flexibleField := schema.String().Optional().Nullable()
// Built-in formats emailSchema := schema.String().Email() urlSchema := schema.String().URL() uuidSchema := schema.String().UUID() dateSchema := schema.String().DateTime() // Custom format with pattern phoneSchema := schema.String(). Format(schema.StringFormat("phone")). Pattern("^\\+?[1-9]\\d{1,14}$")
// Default English context ctx := schema.DefaultValidationContext() // Custom locale for internationalization ctx := schema.NewValidationContext("es") // Spanish // With Go context ctx := schema.DefaultValidationContext(). WithContext(context.Background())
userSchema := schema.Object(). Property("name", schema.String().Required()). Property("email", schema.String().Email().Required()) // Generate JSON Schema jsonSchema := userSchema.JSON() // Convert to JSON jsonBytes, _ := json.Marshal(jsonSchema) fmt.Println(string(jsonBytes))
Output:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["name", "email"],
"additionalProperties": false
}result := schema.Parse(data, ctx) if !result.Valid { for _, err := range result.Errors { fmt.Printf("Field: %v\n", err.Path) fmt.Printf("Value: %s\n", err.Value) fmt.Printf("Error: %s\n", err.Message) fmt.Printf("Code: %s\n", err.Code) } }
// User registration schema with i18n support registrationSchema := schema.Object(). Property("username", schema.String(). Pattern("^[a-zA-Z0-9_]+$"). MinLength(3). MaxLength(20). Required(i18n.S("username is required"))). Property("email", schema.String(). Email(). Required(i18n.S("email address is required"))). Property("password", schema.String(). MinLength(8, i18n.F("password must be at least %d characters", 8)). Pattern(".*[A-Z].*", i18n.S("password must contain uppercase")). Pattern(".*[0-9].*", i18n.S("password must contain number")). Required(i18n.S("password is required"))). Property("age", schema.Int(). Min(13, i18n.F("must be at least %d years old", 13)). Max(120). Optional()). Property("terms", schema.Bool(). Const(true, i18n.S("must accept terms and conditions")). Required()). AdditionalProperties(false) // Validate registration data data := map[string]interface{}{ "username": "johndoe", "email": "john@example.com", "password": "SecurePass123", "age": 25, "terms": true, } result := registrationSchema.Parse(data, schema.DefaultValidationContext()) if result.Valid { fmt.Println("Registration data is valid!") } else { for _, err := range result.Errors { fmt.Printf("Validation error: %s\n", err.Message) } }
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
go test ./...) - Commit your changes (
git commit -am 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Run the test suite:
go test ./...Run tests with coverage:
go test -cover ./...This project is licensed under the MIT License - see the LICENSE file for details.
- nyxstack/i18n - Internationalization support used by this library
- nyxstack/validator - Struct tag based validation using this schema library. Enables validation through struct tags for seamless integration with Go structs.
- Create an issue for bug reports or feature requests
- Check existing issues before creating new ones
- Provide minimal reproducible examples for bugs
Made with β€οΈ by the Nyx team