Skip to main content
Framed content
A config schema defines the structure, types, and constraints of a config instance. It serves as a contract between code and configuration, ensuring that config instances are valid before being deployed to devices. Below are some example schema definitions using the JSON Schema and CUE.
x-miru-config-type: "mobility"
$schema: "https://json-schema.org/draft/2020-12/schema"
type: object
properties:
  max_linear_speed_mps:
    type: number
    minimum: 0.1
    maximum: 5.0
    default: 1.2
  max_angular_speed_radps:
    type: number
    minimum: 0.1
    maximum: 3.0
    default: 1.0
  obstacle_avoidance_enabled:
    type: boolean
    default: true
  navigation_mode:
    type: string
    enum: [conservative, balanced, aggressive]
    default: balanced
  telemetry:
    type: object
    properties:
      upload_interval_sec:
        type: integer
        minimum: 10
        maximum: 300
        default: 60
      heartbeat_interval_sec:
        type: integer
        minimum: 1
        maximum: 60
        default: 10
    required:
      - upload_interval_sec
      - heartbeat_interval_sec
required:
  - max_linear_speed_mps
  - max_angular_speed_radps
  - obstacle_avoidance_enabled
  - navigation_mode
  - telemetry

Supported languages

Config schemas are defined using a schema language—a formal language for describing the structure, constraints, and data types of a configuration. Miru supports: For more information on schema languages, visit the languages section of this guide.

Validating instances

The primary purpose of schemas is to validate config instances. Let’s look at a simple example to see this in action. The following is a toy schema written in JSON Schema.
JSON Schema
$schema: "https://json-schema.org/draft/2020-12/schema"
title: Mobility
type: object
properties:
    max_linear_speed_mps:
        type: number
        minimum: 0.1
        maximum: 5.0
        default: 1.2
    max_angular_speed_radps:
        type: number
        minimum: 0.1
        maximum: 3.0
        default: 1.0
    obstacle_avoidance_enabled:
        type: boolean
        default: true
    navigation_mode:
        type: string
        enum: [conservative, balanced, aggressive]
        default: balanced
    telemetry:
        type: object
        properties:
        upload_interval_sec:
            type: integer
            minimum: 10
            maximum: 300
            default: 60
        heartbeat_interval_sec:
            type: integer
            minimum: 1
            maximum: 60
            default: 10
        required:
        - upload_interval_sec
        - heartbeat_interval_sec
required:
- max_linear_speed_mps
- max_angular_speed_radps
- obstacle_avoidance_enabled
- navigation_mode
- telemetry
The schema defines what constitutes a valid config instance in several different ways:
  • Names the available properties
  • Organizes the configuration structure, placing some properties at the root while nesting other properties in logical groups
  • Gives each property a type, such as number, boolean, etc.
  • Constrains the values of each property—minimums, maximums, enumerations, etc.
  • Supplies default values to properties where appropriate
Most of these constraints are optional, and many features of JSON Schema are omitted here, but this gives you a flavor of what schemas are capable of. Say we are deploying the following config instance.
Unbeknownst to us, the max_angular_speed_radps field exceeds the maximum allowed value of 3.0. Luckily, before deployment to the device, the config instance is validated against the schema, throwing the following error:
Identifying the issue, we correct the max_angular_speed_radps field to use the maximum allowed value of 3.0 and deploy the config instance to the device.
This time the config instance successfully validates against the schema and is deployed to the device. Although simple in concept, schemas are a powerful tool for preventing typos, misconfigurations, and other preventable errors.

Empty schemas

While schemas can provide a lot of value for production deployments, it can be a significant undertaking to define a schema from scratch. Many teams find it best to begin with an empty schema—a schema that accepts any configuration—and gradually add constraints over time. This approach allows you to define the most high value constraints first and gradually transition to stricter and stricter schemas as needed. Below are the empty schemas for JSON Schema and CUE respectively.
$schema: "https://json-schema.org/draft/2020-12/schema"

Properties

Config schemas leverage several properties to adequately describe their format and organize them within their config type. All properties are immutable except for the instance_filepath property, which may be updated at anytime.
language
immutableThe schema language used to define the schema.Currently supported schema languages include:
  • JSON Schema (Draft 2020-12)
  • CUE
Examples: jsonschema, cue
format
immutableThe file format used to define the schema.Some languages, such as JSON Schema, support multiple formats (e.g. JSON, YAML) while others, such as CUE, only support a single format (i.e. CUE lang itself).A schema’s format does not need to match the format of the config instance it validates. Below are the supported schema and config instance formats for each schema language.
LanguageSchema FormatsInstance Formats
JSON SchemaJSON, YAMLJSON
CUECUEJSON
Support for more config instance formats including YAML and JSON-C are coming soon.
Examples: json, yaml, cue
content
immutableThe raw schema definition written in the specified schema language.The exact contents of a schema file is preserved in Miru including any comments, whitespace, and formatting.
digest
immutableA hash of the canonicalized schema content, useful for comparing the contents of two schemas.Digests are computed by converting a schema to it’s canonical form and hashing the result. This is useful for detecting duplicate schemas (even with changes in whitespacing, comments, etc.) and ensuring version integrity.
version
immutableA semantic version, unique for a given config type.Versions must be dot separated integers. You may optionally use a v prefix, a prerelease suffix (e.g. -beta.1, -rc.1), and/or a build suffix (e.g. +metadata).Examples: v1, 1, v2.1, 2.1, v3.2.1, 3.2.1, v4.3.2-beta.1, 4.3.2-rc.1, v5.4.3+metadata, 6.5.4-beta.2+metadata
instance_filepath
mutableThe filepath to deploy config instances (for this schema) on a device relative to the /srv/miru/config_instances directory.The default instance file path for a schema is {my-config-type-slug}.json, which deploys config instances to /srv/miru/config_instances/{my-config-type-slug}.json.Individual config instances may override their schema’s default file path with a custom file path at deployment time.To modify the file path deployed for all future instances of this schema, simply update the instance_filepath property.Examples: /v1/mobility.json, /config/safety.json