This guide demonstrates how to write a Go program that validates JSON files using an embeded CUE schema.
Set up some schema and data files
Create a CUE schema.
You can use any schema that’s relevant to your specific data, but our example uses this simple CUE:
#Schema: {
name?: string
age?: int
}
Create some known-good and known-bad test data.
You may already have some representative test data. This data is relevant to our example schema:
{
"name": "Charlie Cartwright",
"age": 80
}
{
"name": [
"Moby",
"Dick"
],
"age": "173"
}
Verify that your schema accepts and rejects your test data appropriately.
Our example schema is contained in the #Schema
definition, which we reference explicitly:
$ cue vet schema.cue good.json -d '#Schema'
$ cue vet schema.cue bad.json -d '#Schema'
age: conflicting values "173" and int (mismatched types string and int):
./bad.json:6:12
./schema.cue:3:9
name: conflicting values string and ["Moby","Dick"] (mismatched types string and list):
./bad.json:2:13
./schema.cue:2:9
Create a Go program
Initialize a Go module, or use an existing one if that’s more suitable for your situation:
$ go mod init go.example
...
Create a main program.
You can use this example code as a starting point:
package main
import (
"fmt"
"log"
"os"
_ "embed"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/encoding/json"
)
// Embed our schema in a Go string variable.
//
//go:embed schema.cue
var cueSource string
func main() {
ctx := cuecontext.New()
// Build the schema
schema := ctx.CompileString(cueSource).LookupPath(cue.ParsePath("#Schema"))
// Load the JSON file specified (the program's sole argument) as a CUE value
dataFilename := os.Args[1]
dataFile, err := os.ReadFile(dataFilename)
if err != nil {
log.Fatal(err)
}
dataExpr, err := json.Extract(dataFilename, dataFile)
if err != nil {
log.Fatal(err)
}
dataAsCUE := ctx.BuildExpr(dataExpr)
// Validate the JSON data using the schema
unified := schema.Unify(dataAsCUE)
if err := unified.Validate(); err != nil {
fmt.Println("❌ JSON: NOT ok")
log.Fatal(err)
}
fmt.Println("✅ JSON: ok")
}
This example code embeds the CUE from schema.cue
and uses it to validate a
single JSON file, printing the validation result to its standard output stream.
Add a dependency on cuelang.org/go
and ensure the Go module is tidy:
$ go get cuelang.org/go@v0.12.0-0.dev.0.20241203164553-9f217e1d5fcc
...
$ go mod tidy
...
Run the Go program
Verify that the Go program accepts and rejects your test data as expected:
$ go run . good.json
✅ JSON: ok
$ go run . bad.json
❌ JSON: NOT ok
main.go:42: #Schema.name: conflicting values string and ["Moby","Dick"] (mismatched types string and list) (and 1 more errors)
exit status 1
Related content
- Go API:
cue
– package documentation - Go API:
cue/cuecontext
– package documentation - Go API:
encoding/json
– package documentation - Tag: go api – pages explaining and exploring CUE’s Go API