json-schemavalidationapitypescript

JSON Schema Generator: Automatically Create Schemas from JSON Data

·9 min read

What is JSON Schema?

JSON Schema is a vocabulary for annotating and validating JSON data. It lets you define the exact structure of a JSON document — required fields, their types, allowed values, string formats, and numeric ranges. When you validate JSON against a schema, you know precisely whether the data conforms to the contract.

JSON Schema is used for: - Validating API request and response bodies - Generating documentation from schema definitions - Code generation (TypeScript types, Java classes, Go structs) - Form validation in web and mobile apps - Configuration file validation

Generate a Schema Automatically

Writing JSON Schema by hand is tedious. JSONKit's JSON Schema Generator reads any JSON example and produces a draft-07 compatible schema automatically. Visit /json-schema-generator, paste your JSON, and copy the generated schema.

Given this JSON:

json
{
  "id": 1,
  "name": "Ravi Mehta",
  "email": "ravi@example.com",
  "active": true,
  "score": 9.5,
  "tags": ["developer", "mentor"]
}

The generator produces:

json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["id", "name", "email", "active", "score", "tags"],
  "properties": {
    "id": { "type": "integer" },
    "name": { "type": "string" },
    "email": { "type": "string" },
    "active": { "type": "boolean" },
    "score": { "type": "number" },
    "tags": {
      "type": "array",
      "items": { "type": "string" }
    }
  }
}

After Generating — What to Customize

The auto-generated schema is a starting point. You should review and add:

String formats:

json
"email": { "type": "string", "format": "email" }

Numeric constraints:

json
"score": { "type": "number", "minimum": 0, "maximum": 100 }

String length limits:

json
"name": { "type": "string", "minLength": 1, "maxLength": 100 }

Optional fields — remove from required if the field can be absent.

Allow null:

json
"bio": { "type": ["string", "null"] }

Validate JSON Against a Schema

Once you have a schema, use JSONKit's JSON Schema Validator (/json-schema-validator) to check data against it. The validator shows field-level errors with the exact JSON path and the violated keyword.

Validate in Node.js:

javascript
import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);
const validate = ajv.compile(schema);

const valid = validate(data);
if (!valid) console.log(validate.errors);

Validate in Python:

python
import jsonschema

jsonschema.validate(instance=data, schema=schema)
# Raises jsonschema.ValidationError if invalid

Validate in Go:

go
// go get github.com/xeipuuv/gojsonschema
schema, _ := gojsonschema.NewSchema(gojsonschema.NewStringLoader(schemaJson))
result, _ := schema.Validate(gojsonschema.NewStringLoader(dataJson))
if !result.Valid() {
    for _, desc := range result.Errors() {
        fmt.Println(desc)
    }
}

Customizing Generated Schemas

The auto-generated schema infers basic types from your JSON sample. Review and tighten these common additions:

Add string format validation:

json
"email":     { "type": "string", "format": "email" },
"createdAt": { "type": "string", "format": "date-time" },
"website":   { "type": "string", "format": "uri" },
"id":        { "type": "string", "format": "uuid" }

Add numeric constraints:

json
"age":   { "type": "integer", "minimum": 0, "maximum": 150 },
"score": { "type": "number",  "minimum": 0, "maximum": 100 },
"page":  { "type": "integer", "minimum": 1 }

Add string length limits:

json
"name":    { "type": "string", "minLength": 1, "maxLength": 100 },
"bio":     { "type": "string", "maxLength": 2000 },
"zipCode": { "type": "string", "pattern": "^[0-9]{5,6}$" }

Allow null for optional fields:

json
"bio":       { "type": ["string", "null"] },
"middleName":{ "type": ["string", "null"], "maxLength": 50 }

Make fields optional — remove them from the required array.

Reusable Definitions with $defs

For schemas with repeated sub-objects, use $defs to define once and reference everywhere:

json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "Address": {
      "type": "object",
      "required": ["street", "city", "country"],
      "properties": {
        "street":  { "type": "string" },
        "city":    { "type": "string" },
        "country": { "type": "string", "minLength": 2, "maxLength": 2 }
      }
    }
  },
  "type": "object",
  "required": ["id", "name", "billingAddress"],
  "properties": {
    "id":             { "type": "string", "format": "uuid" },
    "name":           { "type": "string" },
    "billingAddress": { "$ref": "#/$defs/Address" },
    "shippingAddress":{ "$ref": "#/$defs/Address" }
  }
}

Union Types with anyOf / oneOf

Use anyOf when a field can match multiple schemas (any one must match):

json
"contact": {
  "anyOf": [
    { "type": "string", "format": "email" },
    { "type": "string", "pattern": "^\\+[0-9]{7,15}$" }
  ]
}

Use oneOf for mutually exclusive variants (exactly one must match):

json
"payment": {
  "oneOf": [
    { "$ref": "#/$defs/CardPayment" },
    { "$ref": "#/$defs/UPIPayment" },
    { "$ref": "#/$defs/NetBanking" }
  ]
}

Array Validation

Control array length and content type:

json
"tags": {
  "type": "array",
  "items": { "type": "string", "minLength": 1 },
  "minItems": 1,
  "maxItems": 10,
  "uniqueItems": true
}

Validate JSON Against Your Schema

Once you have a schema, use JSONKit's JSON Schema Validator to test data against it. The validator shows field-level error paths and the violated keyword.

Node.js (Ajv):

javascript
import Ajv from "ajv";
import addFormats from "ajv-formats";

const ajv = new Ajv({ allErrors: true });
addFormats(ajv);
const validate = ajv.compile(schema);

const valid = validate(data);
if (!valid) {
  validate.errors?.forEach(err =>
    console.error(`${err.instancePath} ${err.message}`)
  );
}

Python (jsonschema):

python
import jsonschema

try:
    jsonschema.validate(instance=data, schema=schema)
    print("Valid")
except jsonschema.ValidationError as e:
    print(f"Invalid at {e.json_path}: {e.message}")

Go (gojsonschema):

go
import "github.com/xeipuuv/gojsonschema"

schema, _ := gojsonschema.NewSchema(gojsonschema.NewStringLoader(schemaJSON))
result, _ := schema.Validate(gojsonschema.NewStringLoader(dataJSON))
if !result.Valid() {
    for _, err := range result.Errors() {
        fmt.Println(err)
    }
}

CI/CD — Validate JSON on Every Push

Add schema validation to your GitHub Actions pipeline:

yaml
- name: Validate API fixtures
  run: |
    npm install -g ajv-cli ajv-formats
    ajv validate -s schemas/user.schema.json -d fixtures/user.json \
      --spec=draft2020 --allowUnionTypes

JSON Schema vs TypeScript vs Zod

| | JSON Schema | TypeScript | Zod | |---|---|---|---| | Runtime validation | Yes (with library) | No (compile-time only) | Yes | | Multi-language | Yes | No | No | | Code generation | Yes (ts-json-schema-generator) | Via JSON to TS tool | Via zod-to-ts | | Learning curve | Medium | Low | Low | | Best for | Cross-language APIs, docs | TypeScript interfaces | TypeScript runtime validation |

Use JSON Schema for API contracts between services in different languages. Use Zod for TypeScript-first runtime validation. Generate a Zod schema or TypeScript interfaces from your JSON in one click.

Try JSON Schema Generator

Generate JSON Schema from any JSON example automatically — no writing by hand.