JSON Schema
JSON Schema
JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. (https://json-schema.org/)
Since all Parro Nexus services are loosely coupled and are only communicating via messages sent trough NATS, we need some kind of contract on the message content. JSON Schema is a way for describing a JSON structure. All messages sent by Parro Nexus are in JSON, so JSON schema gives us a way of creating a single source of truth for the JSON content.
A schema is a (what else) JSON file containing a description for a JSON object. A basic schema file has the following setup:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/topicusonderwijs/parro-connect-schema/tree/main/apps/{{ YOUR_SERVICE_HERE }}/model.json",
"title": "{{ NAME OF YOUR SERVICE}} API model",
"description": "{{ DESCRIPTION OF YOUR SERVICE }}",
"definitions": {
"someObject": {
"title": "Name of object",
"description": "Description of the object",
"type": "object",
"properties": {
"fieldName": {
"description": "A description for fieldName",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"fieldName",
]
},
},
"properties": {
"someObject": {
"$ref": "#/definitions/someObject"
},
},
"additionalProperties": false
}
For Parro Nexus we put all the JSON schema’s in a single repository to create a single source of truth. The parro Nexus repository (https://github.com/topicusonderwijs/parro-connect-schema) contains all the schema’s for all the objects which are sent via NATS. The setup for the repository is to have a directory per domain. Since multiple apps can use the same messages we cannot create a schema per app. So we bundle the schema’s for a domain. We started by creating a schema per app, so there is some legacy in the names of the models.
Since schema’s can change over time bases on the needs of Parro Nexus we added all the schema’s in a v1 directory.
When a model changes with breaking changes we can create a v2 directory and create new schema’s in there.
It is up to the apps to create a solution for backwards compatibility. This can be done by defaulting new fields or by creating a complete new v2 version of the service which only subscribes to the v2 subjects.
There is also a connect directory which contains the common Parro Nexus models. These contain definitions like:
- The NATS subject names
- The NATS header names
- The generic Error message
- The wrapper object for RPC response calls
- The generic ping message
Code generation
Since JSON schema is a standard for describing JSON objects we can generate javascript/typescript objects based on this model. To do this we use the NPM module json-schema-to-typescript.
The repository contains an index.ts file containing the code for generating the typescript objects based on the schema’s.
When running yarn build you will get a CLI asking which model should be build. This will lead to generated typescript files with the objects used in a schema.
These typescript objects can then be copied into your apps. The Parro Nexus repo has this schema repository available as a git submodule, so you can create the models and copy them into your app from within the Parro Nexus project.