Skip to main content

💡 JSON Schema Tips

Welcome to the JSON Schema pro-tips guide! Let's make your schemas clean, robust, and highly reusable.

📝 Metadata (Title & Description)​

Always use the title and description keywords! Rich metadata acts as built-in documentation, helping other developers instantly understand the purpose of your schema.

{
"title": "My Schema",
"description": "This is a schema for my app"
}

🎯 Examples​

Want to make your schema incredibly easy to use? Provide concrete examples!

{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"examples": {
"name": "John Doe"
}
}

💬 Comments​

Need to leave a note for future developers? Use the $comment keyword to inject helpful context directly into the schema.

{
"$comment": "This field is deprecated in v2",
"type": "string"
}

(For more details, check the JSON Schema Docs on Comments)

🛡️ Default Values​

If a property isn't strictly required but needs a fallback, use the default keyword. The config system will automatically provide this value if it is omitted!

{
"type": "object",
"properties": {
"name": {
"type": "string",
"default": "John Doe"
}
}
}

🔒 Required Fields​

By default, everything in a JSON Schema is optional. Use the required array to strictly enforce mandatory properties.

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

Note: Our type generator respects this! The resulting TypeScript will correctly enforce required vs. optional fields.

📜 Enums​

Lock down allowed values using enum! You do not even need to specify the type; the enum can actually mix types if needed.

{
"type": "object",
"properties": {
"color": {
"enum": ["red", "green", "blue"]
}
}
}

Generated TypeScript: color: "red" | "green" | "blue";

🔗 References ($ref)​

Keep your schemas clean and DRY (Don't Repeat Yourself) using the $ref keyword. Even for small schemas (like Id), using refs is a best practice.

Internal Refs​

Reference a definition within the same file:

{
"properties": {
"name": { "$ref": "#/definitions/name" }
},
"definitions": {
"name": { "type": "string" }
}
}

External Refs​

Reference completely different schemas inside the repository using their absolute ID:

{
"properties": {
"name": { "$ref": "https://mapcolonies.com/common/schema/v1" }
}
}

🧩 Schema Composition​

Want to combine schemas? JSON Schema gives you powerful composition tools! (For example, extending the base boilerplate schema). (Read more in the Composition Docs)

AllOf (Merging)​

The allOf keyword merges multiple schemas together. A payload must be valid against all the provided schemas.

⚠️ The additionalProperties Trap

If you use additionalProperties: false inside the sub-schemas, allOf will likely fail! It will demand properties that the other schema explicitly rejects. Read the JSON Schema Docs on Extending carefully!

OneOf & Discriminators​

Use oneOf when a payload must strictly match exactly one schema.

For massive performance gains and better error messages, always pair oneOf with a discriminator! This tells the validator exactly which property determines the schema, skipping unnecessary checks.

{
"storage": {
"type": "object",
"discriminator": { "propertyName": "provider" },
"required": ["provider"],
"oneOf": [
{
"properties": {
"provider": { "const": "s3" },
"credentials": { "type": "string" }
}
}
]
}
}

🔡 String Validations​

  • 📏 Formats: Use format (e.g., email, uri, date-time) to instantly validate complex strings.
  • 🔍 Patterns: Use pattern to enforce strict regex matching.
  • 🪨 Const: Use const when a string must equal one exact, unchangeable value.