Skip to content

# JSON Schema

JSON Schema can automatically be generated for serializable named types exposed via the meta system.

    auto schema = glz::write_json_schema<my_struct>().value();

This can be used for autocomplete, linting, and validation of user input/config files in editors like VS Code that support JSON Schema.

## Registering JSON Schema Metadata

By default `glz::write_json_schema` will write out your fields and types, but additional field may also be registered by specializing `glz::json_schema` or adding a `glaze_json_schema` to your struct.

Example:

    struct meta_schema_t
    {
       int x{};
       std::string file_name{};
       bool is_valid{};
    };

    template <>
    struct glz::json_schema<meta_schema_t>
    {
       schema x{.description = "x is a special integer", .minimum = 1};
       schema file_name{.description = "provide a file name to load"};
       schema is_valid{.description = "for validation"};
    };

The `glz::json_schema` struct allows additional metadata like `minimum`, `maximum`, etc. to be specified for your fields.

Or you can define `glaze_json_schema` in your struct in the same manner:

    struct local_schema_t
    {
       int x{};
       std::string file_name{};
       bool is_valid{};

       struct glaze_json_schema
       {
          glz::schema x{.description = "x is a special integer", .minimum = 1};
          glz::schema file_name{.description = "provide a file name to load"};
          glz::schema is_valid{.description = "for validation"};
       };
    };

## Required Fields

Glaze can automatically mark fields as required in the generated JSON schema based on their nullability and compile options.

### Automatic Required Fields

By default, when using the `error_on_missing_keys` option, non-nullable fields will be marked as required in the schema:

    struct user_config
    {
       std::string username{};  // required (non-nullable)
       std::optional<int> age{}; // optional (nullable)
       int id{};                 // required (non-nullable)
    };

    // Generate schema with required fields
    auto schema = glz::write_json_schema<user_config, glz::opts{.error_on_missing_keys = true}>();

This will generate a schema with `"required": ["username", "id"]`.

### Custom Required Field Logic

You can override the default behavior by providing a custom `requires_key` function in your type's `glz::meta` specialization:

    struct api_request
    {
       std::string endpoint{};
       std::string api_key{};
       std::optional<std::string> optional_param{};
       std::string reserved_field{};  // internal use only
    };

    template <>
    struct glz::meta<api_request>
    {
       // Custom logic to determine which fields are required
       static constexpr bool requires_key(std::string_view key, bool is_nullable)
       {
          // Don't require fields starting with "reserved"
          if (key.starts_with("reserved")) {
             return false;
          }
          // All non-nullable fields are required
          return !is_nullable;
       }
    };

The `requires_key` function receives: - `key`: The name of the field being checked - `is_nullable`: Whether the field type is nullable (e.g., `std::optional`, pointers)

Important: The `requires_key` customization point affects both: 1. JSON Schema generation - which fields are listed in the `"required"` array 2. JSON parsing/validation - which fields are validated as required when `error_on_missing_keys = true`

This allows fine-grained control over which fields are required, useful for: - Excluding internal/reserved fields from requirements - Making non-nullable fields optional without wrapping them in `std::optional` - Making certain nullable fields required based on business logic - Implementing complex validation rules

#### Example: Parsing with `requires_key`

    struct my_struct {
       int required_field{};
       int optional_field{};  // Not std::optional, but we want it to be optional
    };

    template <>
    struct glz::meta<my_struct> {
       static constexpr bool requires_key(std::string_view key, bool is_nullable) {
          if (key == "optional_field") {
             return false;  // Make this field optional
          }
          return !is_nullable;  // Default: non-nullable fields are required
       }
    };

    // Parsing works with error_on_missing_keys = true
    std::string json = R"({"required_field":42})";  // optional_field is missing - OK!
    my_struct obj;
    auto ec = glz::read<glz::opts{.error_on_missing_keys = true}>(obj, json);
    // Success! optional_field was not required due to requires_key

For more detailed information about field validation and the `requires_key` customization point, see Field Validation.