# JSON Schema Validation ## 1. JSONSchema.swift library The schema validation feature was implemented using the [JSONSchema.swift](https://github.com/kylef/JSONSchema.swift) library, [release 0.6.0](https://github.com/kylef/JSONSchema.swift/releases/tag/0.6.0). The library was first added as Package through Swift Package Manager, but it gave this warning: > Module 'JSONSchema' was not compiled with library evolution support; using it means binary compatibility for 'JarvisDataCollection' can't be guaranteed So, instead, the library was downloaded and added locally as a local Package, meaning **it won't update by itself** to a new version. Also, the `JSONSchema/Sources/JSONSchema/format.swift` and `JSONSchema/Sources/JSONSchema/Draft4Validator.swift` files from the library were updated, to include `date-time` format validation. ## 2. Remote referencing For the library to work, it was also necessary to remove all remote references from the schema file, because the library did not support it as of Mar 28, 2021 ([release 0.6.0](https://github.com/kylef/JSONSchema.swift/releases/tag/0.6.0)). Because of that, **every time the schema files are updated, it is necessary to resolve all the remote references** inside the files that will be used. ### 2.1 How to remove remote references? The remote references were resolved only for the notification schema, as it was the only file that would be directly used for validation. For every `$ref` tag in the schema referencing a definition in another file, the tag was replaced with the contents of that definition. Here's an example: The code below is from the file `com.hp.cdm.service.eventing.version.1.resource.notification.schema.json`. These definitions contain an `"eventNotificationAck"` definition. One of it's properties is `"version"`, but its definition (its schema, or "rules") are defined elsewhere, in the file `com.hp.cdm.domain.glossary.version.1.schema.json`. ``` "definitions": "eventNotificationAck": { "additionalProperties": false, "properties": { "ackToken": { "$ref": "#/definitions/ackToken" }, "version": { "$ref": "com.hp.cdm.domain.glossary.version.1.schema.json#/definitions/version" } }, "required": [ "version" ], "type": "object" }, // (...) } ``` This is the "version" defined in the `com.hp.cdm.domain.glossary.version.1.schema.json` file. ``` "definitions": "version": { "description": "Conforms to the version scheme defined for all APIs", "pattern": "(\\d+\\.\\d+\\.\\d+(-\\w+\\.\\d+)?)", "title": "Common Version", "type": "string" } }, } ``` We then replace the remote reference with the content from the glossary file in the notification schema, like this: ``` "definitions": "eventNotificationAck": { "additionalProperties": false, "properties": { "ackToken": { "$ref": "#/definitions/ackToken" }, "version": { "description": "Conforms to the version scheme defined for all APIs", "pattern": "(\\d+\\.\\d+\\.\\d+(-\\w+\\.\\d+)?)", "title": "Common Version", "type": "string" } }, "required": [ "version" ], "type": "object" }, // (...) } ``` Now, the library can read and use the schema file to validate JSON objects. Note that the `"$ref": "#/definitions/ackToken"` is not a problem since it's referencing definitions from the same file. In the specific case of `"version"` since it's used multiple times in the notification file, it's definition was added to the `"definitions"` array, and internally referenced when it was need, like shown below. It's an option to keep the file shorter, since it allows reuse, but it's not necessary to do that with every remote referecing. Just replacing the `$ref` tag with its content is enough. ``` "definitions": "eventNotificationAck": { "additionalProperties": false, "properties": { "ackToken": { "$ref": "#/definitions/ackToken" }, "version": { "$ref": "#/definitions/version" } }, "required": [ "version" ], "type": "object" }, "version": { "description": "Conforms to the version scheme defined for all APIs", "pattern": "(\\d+\\.\\d+\\.\\d+(-\\w+\\.\\d+)?)", "title": "Common Version", "type": "string" } } ```