Skip to content

[go-fan] Go Module Review: santhosh-tekuri/jsonschemaΒ #8030

Description

@github-actions

🐹 Go Fan Report: santhosh-tekuri/jsonschema

Today's pick: github.com/santhosh-tekuri/jsonschema/v5 β€” chosen because a v6 major release (v6.0.2) is available that could eliminate 200+ lines of workaround code the project already has a TODO to investigate.

Module Overview

A Go JSON Schema validator (Drafts 4, 6, 7, 2019-09, 2020-12). Used here to validate MCP Gateway configuration at startup with fail-fast error reporting.

Current Usage in gh-aw

  • Files: 4 (2 production, 2 test) β€” all in internal/config/
  • Key APIs: NewCompiler(), compiler.Draft = jsonschema.Draft7, compiler.AddResource(), compiler.Compile(), schema.Validate(), *jsonschema.ValidationError
  • Patterns: embedded schema compiled once via sync.Once; custom schemas cached per-URL via sync.Map β€” both correct and idiomatic

Research Findings

v5.3.1 (in use) vs v6.0.2 (latest)

The library has a major version 6 at github.com/santhosh-tekuri/jsonschema/v6. The key difference: v6 fully supports Draft 2020-12, which uses ECMAScript 2019 regex β€” including negative lookahead assertions.

The Core Pain Point: fixSchemaBytes()

The embedded schema ($schema: draft-07) uses negative lookahead patterns like ^(?!stdio$|http$).*. Because v5/Draft7 doesn't handle them natively, validation_schema.go contains a ~200-line fixSchemaBytes() function that:

  1. Parses the schema JSON
  2. Removes negative-lookahead patterns, replacing them with not: {enum: [...]} equivalents
  3. Patches missing fields (registry, guard-policies, trustedBots, keepaliveInterval, headers)
  4. Re-serializes

There's already a TODO at line 97 of validation_schema.go flagging this:

// TODO: Investigate if JSON Schema v6 (library upgrade) or Draft 2019-09+/2020-12
// (newer spec) eliminate this workaround. The jsonschema/v6 Go library may handle
// these patterns natively, potentially allowing removal of this function entirely.

Improvement Opportunities

πŸƒ Quick Wins

1. Reduce fragile message-string fallbacks in formatErrorContext

formatErrorContext() dispatches on the KeywordLocation-derived keyword (good, robust) but then falls back to strings.Contains(ve.Message, "additionalProperties") etc. These string-match fallbacks depend on the library's exact wording and can silently break across versions. Since KeywordLocation is already reliably populated, the fallback path should be minimized or removed.

2. Eliminate double JSON round-trip in validateServerAgainstSchema

The server config is json.Marshal-ed and immediately json.Unmarshal-ed to map[string]interface{} just to merge AdditionalProperties. A custom MarshalJSON or a direct struct-to-map builder would be cleaner and avoid the unnecessary allocation.

✨ Feature Opportunities

1. Migrate to jsonschema/v6 β€” eliminate fixSchemaBytes() entirely ← highest value

Upgrading to github.com/santhosh-tekuri/jsonschema/v6 + updating the embedded schema to Draft 2019-09 or 2020-12 should allow the negative-lookahead patterns to work natively, making fixSchemaBytes() (~200 lines + significant test code in fetch_and_fix_schema_test.go) obsolete.

Caveat: v6 has breaking API changes β€” ValidationError field names differ, requiring updates to formatValidationErrorRecursive and formatErrorContext. Needs a spike.

2. Implement a Loader for custom schema fetching

v5 exposes a Loader interface that customizes how schemas are fetched by URL. The project's fetchAndFixSchema() manually handles HTTP with retry logic. Implementing a custom Loader would integrate the retry + fix logic transparently into the compiler's $ref resolution.

πŸ“ Best Practice Alignment

  • sync.Once schema caching β€” already done correctly; cached *Schema is reused across all validations
  • KeywordLocation dispatch β€” already using the correct, version-stable approach; the message-string fallbacks undermine it
  • Add TTL comment on customSchemaCache β€” the sync.Map has no expiry by design (startup-only validation); a comment would prevent well-intentioned but unnecessary "fixes"

Module Summary

Field Value
Module github.com/santhosh-tekuri/jsonschema/v5
Version v5.3.1
Repository https://github.com/santhosh-tekuri/jsonschema
Latest Release v6.0.2 (major version ahead)
Last Reviewed 2026-06-24

References

Recommendations

  1. [HIGH] Spike jsonschema/v6 migration β€” the existing TODO is already pointing at this. Potential to delete ~200 lines of workaround + tests.
  2. [MEDIUM] Remove fragile strings.Contains(msg, ...) fallbacks in formatErrorContext β€” rely on KeywordLocation exclusively.
  3. [LOW] Eliminate double JSON round-trip in validateServerAgainstSchema.
  4. [LOW] Add comment to customSchemaCache explaining no-TTL is intentional.

Next Steps

  • Branch spike: upgrade to jsonschema/v6, update schema $schema to Draft 2020-12, verify fixSchemaBytes can be removed
  • Check v6 ValidationError field compatibility with existing error-formatting code
  • If viable, remove fixSchemaBytes + all associated tests

Generated by Go Fan 🐹 · Run §28084729068

Generated by Go Fan Β· 802.7 AIC Β· ⊞ 34.5K Β· β—·

  • expires on Jul 1, 2026, 8:21 AM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions