Introduction
CUE is a concise and powerful language for describing and constraining data, but
not all systems speak CUE. Some systems can only produce schemas formatted in
JSON Schema. This isn’t a problem for the cue
command because it speaks JSON Schema - letting you use JSON Schema alongside
schemas written in CUE.
In this tutorial you’ll use cue
to convert a JSON Schema to CUE,
and then use the result to validate some data.
Prerequisites
- The
cue
binary – follow the installation instructions if you don’t already usecue
- A tool to edit text files – any text editor you have will be fine, such as VSCode, Notepad, or Vim
- A command terminal –
cue
works on all platforms, so you can use any Linux or macOS terminal, or a Windows terminal such as PowerShell, cmd, or WSL to run commands. - Some awareness of CUE schemata – the language tour’s pages on Constraints and Definitions are a good refresher
This tutorial is written using the following version of cue
:
$ cue version
cue version v0.11.1
...
Steps
This tutorial takes you through converting some JSON Schema to a CUE definition
using the cue import
command,
and then using the result to validate some YAML.
Create a JSON schema file:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": [
"name",
"cuisine",
"tables"
],
"properties": {
"name": {
"type": "string"
},
"cuisine": {
"type": "string"
},
"tables": {
"type": "array",
"items": {
"$ref": "#/$defs/table"
}
}
},
"$defs": {
"table": {
"type": "object",
"additionalProperties": false,
"required": [
"seats"
],
"properties": {
"seats": {
"type": "number",
"minimum": 2,
"maximum": 10
},
"view": {
"type": "boolean"
}
}
}
}
}
This schema validates data that defines a restaurant.
Convert the JSON Schema to a CUE definition called #restaurant
:
$ cue import -l '#restaurant:' -p cuisine schema.json
It’s good practise to tell cue
to place imported CUE inside a package.
Here, we choose the cuisine
package.
cue import
creates the file schema.cue
containing this CUE:
package cuisine
#restaurant: {
@jsonschema(schema="https://json-schema.org/draft/2020-12/schema")
close({
name!: string
cuisine!: string
tables!: [...#table]
})
#table: close({
seats!: >=2 & <=10
view?: bool
})
}
CUE natively understands JSON Schema, and is able to convert all of the JSON Schema constraints into CUE constraints. Notice the CUE schema is also considerably more concise and readable.
Create some data files that contain restaurant details:
name: The Split Pea
cuisine: Contemporary
tables:
- seats: 4
view: true
- seats: 6
name: Il Pomodoro Marcio
cuisine: Italian
tables:
- seats: 100
- seats: 8
view: true
One of these files contains a deliberate problem that cue
will catch for us,
shortly. If you spotted the problem while entering the data, make sure you
didn’t correct it!
Validate the data using the schema and constraints:
$ cue vet -d '#restaurant' schema.cue *.yml
tables.0.seats: invalid value 100 (out of bound <=10):
./schema.cue:12:17
./pomodoro.yml:4:12
cue vet
outputs nothing when validation succeeds. But as you can see, there
are some validation errors.
Fix the data validation error by updating your pomodoro.yml
file:
name: Il Pomodoro Marcio
cuisine: Italian
tables:
- seats: 10
- seats: 8
view: true
Re-validate the data using the schema and constraints:
$ cue vet -d '#restaurant' schema.cue *.yml
The “silent” lack of output from cue vet
confirms that the fixed data
validates successfully.
Conclusion
You’ve completed this tutorial - well done!
In this tutorial you converted JSON Schema to CUE using cue import
, and then
used the resulting CUE to catch and fix an error in some data.