1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
# JSON Schema
JSON Schema can automaticly be generated for serializable named types exposed via the meta system.
```c++
std::string schema = glz::write_json_schema<my_struct>();
```
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:
```c++
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:
```c++
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:
```c++
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:
```c++
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`
```c++
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](field-validation.md).
|