Skip to content

Feature request: Add possibility to register custom formats #152

@AlexMinaev19

Description

@AlexMinaev19

Feature

We can already enable format validation when creating a validator. Currently, we have some built-in formats (for example, IPv4, IPv6, email, etc.). But we can't define custom formats (for example, phone numbers, country codes, etc.) or override existing ones (like email). Underlying library santhosh-tekuri/jsonschema have support for such thing via func (*Compiler) RegisterFormat.

Proposal

Add new field to config/config.go ValidationOptions that will hold information about new formats.

type ValidationOptions struct {
    RegexEngine       jsonschema.RegexpEngine
    FormatAssertions  bool
    ContentAssertions bool
    Formats           map[string]func(v any) error
}

Add new function to add custom format in file config/config.go.

// WithCustomFormat adds custom formats and their validators that checks for custom 'format' assertions
func WithCustomFormat(name string, validator func(v any) error) Option {
    return func(o *ValidationOptions) {
        // todo check that map is initialized

        o.Formats[name] = validator
    }
}

Also, we have to add register of custom formats in jsonschema.Compiler.

// ConfigureCompiler configures a JSON Schema compiler with the desired behavior.
func ConfigureCompiler(c *jsonschema.Compiler, o *config.ValidationOptions) {
    if o == nil {
        // Sanity
        return
    }

    // nil is the default so this is OK.
    c.UseRegexpEngine(o.RegexEngine)

    // Enable Format assertions if required.
    if o.FormatAssertions {
        c.AssertFormat()
    }

    // Content Assertions
    if o.ContentAssertions {
        c.AssertContent()
    }

    // Register custom formats
    for n, v := range o.Formats {
        c.RegisterFormat(&jsonschema.Format{
            Name:     n,
            Validate: v,
        })
    }
}

This should be enough to register custom formats. This functionality still relys on FormatAssertions enabled and it's fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions