A robust, performant Golang library for generating random, schema-compliant JSON data from JSON Schema definitions. Perfect for testing, fuzzing, and mock data generation.
- ✅ JSON Schema Compliant: Supports Draft 2020-12 and Draft-07
- ✅ Realistic Fake Data: Uses gofakeit for generating realistic mock data
- ✅ Deterministic Generation: Seedable random generation for reproducible results
- ✅ Type Safe: Strong typing with Go structs
- ✅ Comprehensive: Supports most JSON Schema keywords
- ✅ Configurable: Control depth limits, field generation, and more
- ✅ Well Tested: Extensive test coverage
go get github.com/sarathsp06/schemagenpackage main
import (
"fmt"
"log"
"github.com/sarathsp06/schemagen"
)
func main() {
schema := `{
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 3},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 18, "maximum": 100}
},
"required": ["name", "email"]
}`
gen := schemagen.NewGenerator()
result, err := gen.Generate([]byte(schema))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", result)
// Output: map[age:42 email:john.doe@example.com name:Alice]
}gen := schemagen.NewGenerator().
SetSeed(12345). // For deterministic output
SetMaxDepth(10). // Limit recursion depth
SetGenerateAllFields(true) // Generate optional fields too| Option | Default | Description |
|---|---|---|
SetSeed(int64) |
Current timestamp | Set seed for deterministic generation |
SetMaxDepth(int) |
10 | Maximum recursion depth for nested objects |
SetGenerateAllFields(bool) |
false | Generate all fields vs. only required ones |
| Keyword | Support | Description |
|---|---|---|
type |
✅ | Single or array of types: string, number, integer, boolean, object, array, null |
enum |
✅ | Pick random value from enumerated list |
const |
✅ | Return exact constant value |
| Keyword | Support | Example |
|---|---|---|
minLength |
✅ | {"type": "string", "minLength": 5} |
maxLength |
✅ | {"type": "string", "maxLength": 10} |
pattern |
✅ | {"type": "string", "pattern": "^[0-9]{5}$"} |
format |
✅ | See Supported Formats |
| Keyword | Support | Example |
|---|---|---|
minimum |
✅ | {"type": "integer", "minimum": 0} |
maximum |
✅ | {"type": "integer", "maximum": 100} |
exclusiveMinimum |
✅ | {"type": "number", "exclusiveMinimum": 0} |
exclusiveMaximum |
✅ | {"type": "number", "exclusiveMaximum": 1} |
multipleOf |
✅ | {"type": "integer", "multipleOf": 5} |
| Keyword | Support | Example |
|---|---|---|
properties |
✅ | Define object fields with schemas |
required |
✅ | List of required field names |
additionalProperties |
✅ | Allow extra properties (boolean or schema) |
| Keyword | Support | Example |
|---|---|---|
items |
✅ | Schema for array items (single or tuple) |
minItems |
✅ | {"type": "array", "minItems": 2} |
maxItems |
✅ | {"type": "array", "maxItems": 10} |
| Keyword | Support | Behavior |
|---|---|---|
oneOf |
✅ | Randomly select one sub-schema |
anyOf |
✅ | Randomly select one sub-schema |
allOf |
✅ | Generate from first schema (MVP) |
The library uses gofakeit to generate realistic data for these formats:
| Format | Example Output |
|---|---|
uuid |
550e8400-e29b-41d4-a716-446655440000 |
email |
john.doe@example.com |
date-time |
2023-10-15T14:30:00Z |
date |
2023-10-15 |
time |
14:30:00 |
ipv4 |
192.168.1.1 |
ipv6 |
2001:0db8:85a3:0000:0000:8a2e:0370:7334 |
uri / url |
https://example.com/path |
hostname |
example.com |
schema := `{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"id": {"type": "string", "format": "uuid"},
"name": {"type": "string", "minLength": 3},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 18, "maximum": 120}
},
"required": ["id", "name", "email"]
},
"tags": {
"type": "array",
"items": {"type": "string"},
"minItems": 1,
"maxItems": 5
},
"active": {"type": "boolean"}
},
"required": ["user", "active"]
}`
gen := schemagen.NewGenerator()
result, _ := gen.Generate([]byte(schema))gen := schemagen.NewGenerator()
jsonBytes, err := gen.GenerateBytes([]byte(schema))
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonBytes))func TestMyFunction(t *testing.T) {
gen := schemagen.NewGenerator().SetSeed(12345)
// Generate same data every time for reproducible tests
result1, _ := gen.Generate([]byte(schema))
// Reset with same seed
gen.SetSeed(12345)
result2, _ := gen.Generate([]byte(schema))
// result1 and result2 will be identical
}schema := `{
"oneOf": [
{
"type": "object",
"properties": {
"type": {"const": "user"},
"username": {"type": "string"}
}
},
{
"type": "object",
"properties": {
"type": {"const": "admin"},
"adminId": {"type": "integer"}
}
}
]
}`The library validates schemas and returns errors for:
- Invalid JSON Schema syntax
- Conflicting constraints (e.g.,
minimum > maximum) - Maximum recursion depth exceeded
- Unsupported schema features
gen := schemagen.NewGenerator().SetMaxDepth(3)
result, err := gen.Generate([]byte(deeplyNestedSchema))
if err != nil {
// Handle error: might be depth exceeded or invalid schema
log.Printf("Generation failed: %v", err)
}- $ref: Reference resolution not yet implemented (future enhancement)
- allOf: Currently generates from first schema only (complete merge planned)
- additionalProperties: Limited support (generates 0-2 extra properties when enabled)
The library validates constraints and returns errors for impossible schemas:
// This will return an error
schema := `{"type": "integer", "minimum": 100, "maximum": 10}`Run the test suite:
go test -vRun tests with coverage:
go test -cover- github.com/brianvoe/gofakeit/v7 - Realistic fake data generation
- github.com/lucasjones/reggen - Regex pattern string generation
Contributions are welcome! Please feel free to submit issues or pull requests.
- Clone the repository
- Run tests:
go test -v - Make your changes
- Ensure all tests pass
- Submit a pull request
Future enhancements planned:
- Full
$refand definitions support - Complete
allOfschema merging - More format types (email variants, phone numbers, etc.)
- Custom format handlers
- Performance optimizations for large schemas
- CLI tool for generating test data
Built with: