Lehks
Lehks

Reputation: 3166

AJV - Reference external schema without adding it first

Is it possible to use AJV to reference a schema that was previously not added through addSchema()?

I want to resolve a reference like this:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "id": {
            "$ref": "project-id.schema.json#/definitions/id"
        }
    }
}

without explicitly adding project-id.schema.json first.

Upvotes: 4

Views: 3442

Answers (1)

customcommander
customcommander

Reputation: 18901

Given

answer.json

{
  "$id": "stackoverflow://schemas/answer.json",
  "type": "object",
  "properties": {
    "id": {
      "$ref": "id.json#"
    }
  }
}

id.json

{
  "$id": "stackoverflow://schemas/id.json",
  "type": "string"
}

Adding all schemas at once via the schemas option

const Ajv = require('ajv');
const ajv = new Ajv({
  schemas: [
    require('./id.json'),
    require('./answer.json')
  ]
});

const validate = ajv.getSchema('stackoverflow://schemas/answer.json');

validate(42);
//=> false
validate({id: 42});
//=> false
validate({id: '🌯'});
//=> true

Loading referenced schemas with the loadSchema option

In this case you do need to pass the schema you want to compile as an object but if that schema contains references to other schemas not known by Ajv already, these will be loaded via loadSchema:

const Ajv = require('ajv');
const ajv = new Ajv({
  loadSchema: function (uri) {
    return new Promise((resolve, reject) => {
      if (uri === 'stackoverflow://schemas/id.json') {
        resolve(require('./id.json')); // replace with http request for example
      } else {
        console.log('wat')
        reject(new Error(`could not locate ${uri}`));
      }
    });
  }
});

const test = async () => {
  // Schemas referenced in answer.json will be loaded by the loadSchema function
  const validate = await ajv.compileAsync(require('./answer.json'));
  validate(42) //=> false
  validate({id: 42}) //=> false
  validate({id: '🌯'}) //=> true
}

test();

Upvotes: 4

Related Questions