Skip to main content
A schema language is a formal language for describing the structure, constraints, and data types of a configuration. Miru config schemas are defined in a supported schema language to validate configurations before deployment. Currently, the following languages are supported: This section covers key integration points for a each language. For more general information about the strengths and weaknesses of each language, check out our blog post comparing JSON Schema, CUE, and Protocol Buffers: Config Wars.

JSON Schema

JSON Schema is probably the most popular schema language. With origins dating back to 2010, JSON Schema was originally built for API validation, but has since found its way into configuration systems across web, cloud, and robotics infrastructure.

Example

Below is an example JSON Schema to give you a flavor of what JSON Schema looks like.
JSON Schema
$schema: "https://json-schema.org/draft/2020-12/schema"
title: Communication Configuration Schema
type: object
required:
  - control_loop_rate_hz
  - watchdog_timeout_ms
  - network
  - logging
  - error_handling
properties:
  control_loop_rate_hz:
    type: integer
    description: Control loop frequency in Hertz
    minimum: 1
    maximum: 1000  
    default: 50
  watchdog_timeout_ms:
    type: integer
    description: Watchdog timeout duration in milliseconds
    minimum: 100   
    maximum: 5000  
    default: 500
  network:
    type: object
    required:
      - max_latency_ms
      - connection_timeout_ms
      - reconnect_attempts
      - reconnect_interval_ms
      - heartbeat_interval_ms
    properties:
      max_latency_ms:
        type: integer
        description: Maximum acceptable network latency in milliseconds
        minimum: 10    
        maximum: 1000  
        default: 100
      connection_timeout_ms:
        type: integer
        description: Connection timeout duration in milliseconds
        minimum: 100    
        maximum: 10000  
        default: 2000
      reconnect_attempts:
        type: integer
        description: Number of reconnection attempts
        minimum: 1
        maximum: 10    
        default: 3
      reconnect_interval_ms:
        type: integer
        description: Interval between reconnection attempts in milliseconds
        minimum: 100    
        maximum: 5000   
        default: 1000
      heartbeat_interval_ms:
        type: integer
        description: Interval between heartbeat messages in milliseconds
        minimum: 50     
        maximum: 1000   
        default: 250
  logging:
    type: object
    required:
      - enable_packet_logging
      - log_level
      - max_log_size_mb
      - retain_logs_days
    properties:
      enable_packet_logging:
        type: boolean
        description: Enable or disable packet logging
        default: true
      log_level:
        type: string
        description: Logging level
        enum: ["debug", "info", "warn", "error"]
        default: "info"
      max_log_size_mb:
        type: integer
        description: Maximum log file size in megabytes
        minimum: 1
        maximum: 1024  
        default: 100
      retain_logs_days:
        type: integer
        description: Number of days to retain log files
        minimum: 1
        maximum: 90    
        default: 30
  error_handling:
    type: object
    required:
      - max_consecutive_failures
      - failure_timeout_ms
      - enable_auto_recovery
    properties:
      max_consecutive_failures:
        type: integer
        description: Maximum number of consecutive failures allowed
        minimum: 1
        maximum: 20    
        default: 5
      failure_timeout_ms:
        type: integer
        description: Timeout duration for failure handling in milliseconds
        minimum: 100    
        maximum: 30000  
        default: 5000
      enable_auto_recovery:
        type: boolean
        description: Enable or disable automatic recovery from failures
        default: true
Although many of JSON Schema’s capabilities are omitted in this example, you’ll find some of the most common keywords including:
  • $schema - specifies the JSON Schema draft version
  • type - the data type of a property
  • required - signals that a property is required
  • properties - the sub-fields of an object
  • default - the default value of a property
  • description - the description of a property
  • enum - a constrained list of allowed values for a property (only for string types)
  • minimum - the minimum value of a property (only for numeric types)
  • maximum - the maximum value of a property (only for numeric types)
For a comprehensive list of JSON Schema keywords, visit the official JSON Schema website. We also find the official test suite highly useful, containing a vast number of simple JSON Schema examples.

Drafts

While JSON Schema has a variety of drafts, only Draft 2020-12, the most recent stable draft, is supported. When specifying the $schema keyword in a schema (which is recommended), it must be set to the following value:
$schema: "https://json-schema.org/draft/2020-12/schema"
If the $schema keyword is omitted from a schema, the schema is automatically interpreted as Draft 2020-12.

Keywords

The full suite of Draft 2020-12 keywords are supported. For a comprehensive list of JSON Schema keywords, visit the official JSON Schema website. We also find the official test suite highly useful, containing a vast number of simple JSON Schema examples.

File formats

While JSON Schema was originally built for JSON data, it is not exclusive to JSON. As you may have noticed, we’re partial to writing JSON Schema in YAML for readability (no excessive brackets and we can use comments!). JSON Schema can be written in the following formats:
  • JSON (.json)
  • YAML (.yaml, .yml)
Schemas defined in JSON Schema can validate instances in the following formats:
  • JSON (.json)
Support for more instance formats including YAML and JSON-C are coming soon.
The format of a schema does not need to match the format of the config instance it validates. For example, a YAML formatted JSON Schema can validate a JSON formatted config instance.

CUE

CUE (Configure, Unify, Execute) is another opens-source schema language, useful for defining valid fields, types, and values for a config. CUE was developed at Google by Marcel van Lohuizen, one of the original creators of Go. The original motivation stemmed from Google’s internal struggles in managing complex, large-scale configurations for infrastructure and applications. JSON and YAML were too weak for expressing constraints, logic, or composition, so CUE set out to solve that. Instead of building and managing external tools to validate, patch, or generate configs, CUE itself is a fully programmable config engine. This means CUE wholly encapsulates the configuration data, the schema, and the logic (how to derive those config values).

Example

Below is an example CUE schema to give you a flavor of what CUE looks like.
CUE
@miru(config_type="communication")

control_loop_rate_hz: number & >=1 & <=1000 | *50
watchdog_timeout_ms: number & >=100 & <=5000 | *500

network: {
	max_latency_ms: number & >=10 & <=1000 | *100
	connection_timeout_ms: number & >=100 & <=10000 | *2000
	reconnect_attempts: number & >=1 & <=10 | *3
	reconnect_interval_ms: number & >=100 & <=5000 | *1000
	heartbeat_interval_ms: number & >=50 & <=1000 | *250
}

logging: {
	enable_packet_logging: bool | *true
	log_level: "debug" | "info" | "warn" | "error" | *"info"
	max_log_size_mb: number & >=1 & <=1024 | *100
	retain_logs_days: number & >=1 & <=90 | *30
}

error_handling: {
	max_consecutive_failures: number & >=1 & <=20 | *5
	failure_timeout_ms: number & >=100 & <=30000 | *5000
	enable_auto_recovery: bool | *true
}
Although many of CUE’s capabilities are omitted in this example, you’ll find some of the most commonly used features including:
  • type specification - number, string, bool, etc.
  • numeric constraints- >=, <=, ==, !=, =~, !~, etc.
  • default values - | *value
  • enumerations - | "value1" | "value2" | "value3"
  • intersection of constraints - &
As you can see, CUE inlines constraints directly with type definitions, making schemas significantly more concise than JSON Schema. For more information on the supported features of CUE, visit the official CUE website.

CUE version

Miru fully supports CUE and stays up to date with the latest CUE features and syntax. As of writing, Miru uses CUE API v0.14.2.

File formats

Unlike JSON Schema, CUE can only be written in the CUE file format and must have the .cue extension:
  • CUE (.cue)
Similar to JSON Schema though, CUE schemas can validate config instances in the following formats:
  • JSON (.json)
Support for more instance formats including YAML and JSON-C are coming soon.