Nested Object Validation in JSON Schema

Validate deeply nested JSON objects with JSON Schema. Learn to define hierarchical structures, nested required fields, and multi-level object composition.

Object Constraints

JSON Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": { "type": "string", "minLength": 1 },
        "age": { "type": "integer", "minimum": 0 }
      },
      "required": ["name"]
    },
    "address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" },
        "country": { "type": "string" },
        "postalCode": { "type": "string" },
        "coordinates": {
          "type": "object",
          "properties": {
            "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
            "longitude": { "type": "number", "minimum": -180, "maximum": 180 }
          },
          "required": ["latitude", "longitude"]
        }
      },
      "required": ["street", "city", "country"]
    }
  },
  "required": ["user", "address"]
}

Test Data

{
  "user": {
    "name": "Alice Chen",
    "age": 32
  },
  "address": {
    "street": "123 Main Street",
    "city": "San Francisco",
    "country": "US",
    "postalCode": "94102",
    "coordinates": {
      "latitude": 37.7749,
      "longitude": -122.4194
    }
  }
}

Detailed Explanation

Nested Object Validation

Real-world JSON data is rarely flat — it contains objects within objects. JSON Schema handles nested structures naturally by defining sub-schemas for each level of nesting.

Basic Nesting

{
  "type": "object",
  "properties": {
    "address": {
      "type": "object",
      "properties": {
        "city": { "type": "string" }
      },
      "required": ["city"]
    }
  }
}

The inner schema validates address as an object with a required city string property. Each nesting level has its own independent properties, required, and other keywords.

How the Example Schema Works

The schema defines a two-level nested structure with an optional third level:

Level 1 — the root object requires both user and address.

Level 2user is an object with a required name and an optional age. The address object requires street, city, and country, with optional postalCode and coordinates.

Level 3coordinates is an object nested inside address, with required latitude (range -90 to 90) and longitude (range -180 to 180).

The test data passes all three levels: the user has a name, the address has all required fields, and the coordinates are valid geographic values.

Required at Each Level

A critical point: each object has its own required array. The root-level required: ["user", "address"] does not make user.name required — that is controlled by the required inside the user sub-schema.

Avoiding Deep Nesting with $ref

When schemas get deeply nested, readability suffers. Use $ref with $defs to flatten the structure:

{
  "type": "object",
  "properties": {
    "address": { "$ref": "#/$defs/Address" }
  },
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "city": { "type": "string" },
        "coordinates": { "$ref": "#/$defs/GeoPoint" }
      }
    },
    "GeoPoint": {
      "type": "object",
      "properties": {
        "latitude": { "type": "number" },
        "longitude": { "type": "number" }
      }
    }
  }
}

This approach keeps each definition at the top level, making schemas easier to read, test, and reuse. See the ref-definitions example for a deep dive into $ref.

Error Path Reporting

When validation fails in a nested structure, good validators report the JSON Pointer path to the error (e.g., /address/coordinates/latitude). This makes debugging deeply nested structures straightforward.

Use Case

Use nested object schemas for API endpoints that accept structured data like user profiles with addresses, orders with line items, or configuration objects with grouped settings. Nested validation ensures every level of your data hierarchy is correct before processing.

Try It — JSON Schema Validator

Open full tool