Skip to content
/ ktson Public

Yet another json schema validator. Implemented with kotlin

License

Notifications You must be signed in to change notification settings

rawo/ktson

Repository files navigation

KtSON

Kotlin Java License Test Coverage

JSON Schema validator for Kotlin with comprehensive support for JSON Schema Draft 2019-09 and 2020-12.

NOTE

This project is a playground for testing AI agents as a day-to-day tools in programming.
You can see the summaries and results from discussions with AI in the ./docs directory.
Most of the code refactoring were performed by AI agent with supervision and code review done by human.

Table of Contents

Features

Comprehensive Validation

  • Full type validation (string, number, integer, boolean, object, array, null)
  • String constraints (minLength, maxLength, pattern, format)
  • Numeric constraints (minimum, maximum, multipleOf, exclusive bounds)
  • Object constraints (properties, required, additionalProperties, patternProperties, dependencies)
  • Array constraints (items, prefixItems, contains, uniqueItems, minItems, maxItems)

Advanced Schema Features

  • Schema references ($ref) with local and fragment support
  • Schema combiners (allOf, anyOf, oneOf, not)
  • Conditional validation (if/then/else)
  • Property name validation
  • Dependent schemas and required properties

Tech Stack

Core

  • Language: Kotlin 2.2.20
  • JVM: Java 21
  • Build Tool: Gradle 9.1.0

Dependencies

  • kotlinx-serialization-json - JSON parsing and manipulation
  • kotest - Testing framework
  • ktlint - Code style and quality

Package: org.ktson

Getting Started

Prerequisites

  • JDK 21 or higher
  • Gradle 9.1.0 or higher (or use the included wrapper)

Installation

Gradle (Kotlin DSL)

dependencies {
    implementation("org.ktson:ktson:0.0.1-SNAPSHOT")
}

Gradle (Groovy)

dependencies {
    implementation 'org.ktson:ktson:0.0.1-SNAPSHOT'
}

Maven

<dependency>
    <groupId>org.ktson</groupId>
    <artifactId>ktson</artifactId>
    <version>0.0.2-SNAPSHOT</version>
</dependency>

Basic Usage

Validating JSON Against a Schema

import org.ktson.*
import kotlinx.serialization.json.*

fun main() {
    // Create a JSON schema
    val schemaJson = """
    {
        "type": "object",
        "properties": {
            "name": { "type": "string" },
            "age": { "type": "integer", "minimum": 0 }
        },
        "required": ["name", "age"]
    }
    """
    
    // Create instance data
    val instanceJson = """
    {
        "name": "John Doe",
        "age": 30
    }
    """
    
    // Validate
    val validator = JsonValidator()
    val result = validator.validate(instanceJson, schemaJson, SchemaVersion.DRAFT_2020_12)
    
    when (result) {
        is ValidationResult.Valid -> println("✓ Validation successful!")
        is ValidationResult.Invalid -> {
            println("✗ Validation failed:")
            result.errors.forEach { error ->
                println("  - ${error.path}: ${error.message}")
            }
        }
    }
}

Using JsonElement

import org.ktson.*
import kotlinx.serialization.json.*

val schema = buildJsonObject {
    put("type", "string")
    put("minLength", 3)
    put("maxLength", 10)
}

val instance = JsonPrimitive("hello")

val validator = JsonValidator()
val jsonSchema = JsonSchema.fromElement(schema, SchemaVersion.DRAFT_2020_12)
val result = validator.validate(instance, jsonSchema)

Validating Schema Structure

val validator = JsonValidator(enableMetaSchemaValidation = true)
val schema = JsonSchema.fromString(schemaJson, SchemaVersion.DRAFT_2020_12)

val result = validator.validateSchema(schema)
if (result is ValidationResult.Invalid) {
    println("Invalid schema:")
    result.errors.forEach { println("  - ${it.message}") }
}

Working with $ref

val schema = """
{
    "${'$'}defs": {
        "address": {
            "type": "object",
            "properties": {
                "street": { "type": "string" },
                "city": { "type": "string" }
            }
        }
    },
    "type": "object",
    "properties": {
        "billing": { "${'$'}ref": "#/${'$'}defs/address" },
        "shipping": { "${'$'}ref": "#/${'$'}defs/address" }
    }
}
"""

For more examples, see docs/REF_USAGE_EXAMPLES.md and src/main/kotlin/org/ktson/Example.kt.

Available Scripts

Build

# Build the project
./gradlew build

# Compile only
./gradlew compileKotlin

# Create JAR
./gradlew jar

Testing

# Run all tests (excludes performance tests for speed)
./gradlew test

# Run specific test suite
./gradlew test --tests "Draft201909ValidationTest"
./gradlew test --tests "OfficialTestSuiteRunner"

# Run performance tests (on demand)
./gradlew performanceTest

# Run all tests including performance
./gradlew test performanceTest

Code Quality

# Check code style with ktlint
./gradlew ktlintCheck

# Auto-format code with ktlint
./gradlew ktlintFormat

Project Scope

Supported JSON Schema Versions

  • JSON Schema Draft 2020-12 (primary support)
  • JSON Schema Draft 2019-09 (full support)

Feature Completeness

Feature Category Status Coverage
Type Validation ✅ Complete 100%
String Validation ✅ Complete 100% (including Unicode codepoints)
Numeric Validation ✅ Complete 100%
Object Validation ✅ Complete 95%
Array Validation ✅ Complete 95%
Schema Combiners ✅ Complete 100%
Conditional Validation ✅ Complete 100%
References ($ref) ✅ Complete Local references only
Format Validation ⚠️ Partial Basic formats (email, URI, date, time, IPv4, IPv6, UUID)
Official Test Suite ✅ 92.8% 2,205/2,376 passing

Not Implemented:

  • unevaluatedProperties and unevaluatedItems (Draft 2020-12 features)
  • Remote schema references (HTTP/HTTPS)
  • Full $recursiveRef and $dynamicRef dynamic scoping
  • Some advanced format validators

See docs/IMPLEMENTATION_STATUS.md for detailed feature breakdown.

Known Limitations

  1. Stack Overflow RiskRESOLVED

    • ✅ Global recursion depth limiting implemented (default: 1000 levels)
    • ✅ Configurable via maxValidationDepth constructor parameter
    • ✅ Thread-safe implementation
    • ✅ Covers all recursive validation paths
    • See docs/STACK_OVERFLOW_RISK_ANALYSIS.md for historical analysis
  2. Remote References

    • Only local references (#/...) are supported
    • HTTP/HTTPS schema references are not implemented
  3. Advanced Draft 2020-12 Features

    • unevaluatedProperties and unevaluatedItems not supported
    • Full dynamic scoping for $dynamicRef not implemented
  4. Format Validation

    • Basic assertion mode only
    • Limited format validators (no regex-heavy formats like hostname)

Project Status

Version: 0.0.1-SNAPSHOT
Status: ⚠️ Pre-release (Beta)

Test Coverage

  • Custom Tests: 155 tests (100% passing)

    • Draft 2019-09: 47 tests
    • Draft 2020-12: 54 tests
    • Edge cases & thread safety: 39 tests
    • Depth limit protection: 15 tests
  • Official JSON Schema Test Suite: 2,376 tests

    • ✅ Passing: 2,205 (92.8%)
    • ❌ Failing: 171 (7.2%)
    • Primary failures: unevaluatedProperties and unevaluatedItems
  • Performance Tests: 6 tests (100% passing)

    • Tested with schemas up to 50MB
    • Tested with data up to 20MB
    • Concurrent validation verified

Recent Changes

  • Stack overflow protection implemented (configurable depth limiting)
  • ✅ Converted from async to synchronous API
  • ✅ Package migrated from com.ktson to org.ktson
  • ✅ Upgraded to Kotlin 2.2.20 and Java 21
  • ✅ Added Ktlint for code quality
  • ✅ Extracted schema keywords to constants
  • ✅ Performance test suite added
  • ✅ Thread-safe ReferenceResolver (stateless implementation)

Roadmap

Before 1.0 Release:

  • Implement recursion depth limitingCOMPLETED
  • Add configurable validation limitsCOMPLETED
  • Implement unevaluatedProperties and unevaluatedItems
  • Add more format validators
  • Improve error messages

Future Enhancements:

  • Remote schema reference support
  • Full $dynamicRef dynamic scoping
  • Schema caching improvements
  • Streaming validation for large datasets
  • GraalVM native image support

Documentation

Comprehensive documentation is available in the docs directory:

Getting Started

Testing

Technical

Migration & History

See docs/README.md for a complete documentation index.

Performance

KtSON demonstrates excellent performance with large and complex schemas:

Test Case Schema Size Data Size Execution Time Memory Used
Nested Objects 25.2 MB 10.2 MB 84ms 73 MB
Large Arrays 905 KB 80 KB 7ms 1 MB
Complex Properties 534 KB 205 KB 6ms 4 MB
Combiners 221 KB 38 KB 4ms 1 MB
Pattern Properties 63 KB 148 KB 48ms 175 MB
Concurrent (10 threads) 50 MB 20 MB 19ms avg 392 MB

Key Characteristics:

  • Fast: Most validations complete in single-digit milliseconds
  • Scalable: Handles schemas up to 50MB efficiently
  • Thread-safe: Zero synchronization overhead
  • Memory efficient: Proportional to schema complexity

See docs/PERFORMANCE_TEST_RESULTS.md for detailed benchmarks.

Code Quality

KtSON follows strict code quality standards:

  • Code Style: Enforced with Ktlint 1.7.1
  • Style Guide: IntelliJ IDEA default Kotlin conventions
  • Test Coverage: 2,500+ tests across multiple suites
  • Thread Safety: Verified with concurrent validation tests
  • Documentation: Comprehensive inline documentation and separate docs

Check code style:

./gradlew ktlintCheck

Auto-format code:

./gradlew ktlintFormat

License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2024 KtSON Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Note: This is a pre-release version. While the validator is functional and passes 92.8% of official tests, it has known limitations (particularly around recursion depth) that should be addressed before production use with untrusted schemas. See STACK_OVERFLOW_RISK_ANALYSIS.md for details.

About

Yet another json schema validator. Implemented with kotlin

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages