How can I access `definitions` in schema-store using `$ref`?
imjuni opened this issue · 1 comments
Motivation
When developing a RESTful server using Express.js, Fastify.js, etc. in a Node environment, it uses json-schema to validate API request inputs. If you're using json-schema to validate request inputs, integrating multiple schemas can be more manageable as the number of APIs grows.
interface IPeople {
firstName: string;
lastName: string;
}
interface IStudent extends IPeople {
major: string;
}
interface IProfessor extends IPeople {
room: number;
}
The example above is in typescript, but it can also be expressed in json-schema.
{
"$id": "IPeople",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
},
}
{
"$id": "IStudent",
"properties": {
"major": {
"type": "string"
},
"$ref": "IPeople"
},
}
{
"$id": "IProfessor",
"properties": {
"room": {
"type": "number"
},
"$ref": "IPeople"
},
}
It's useful to have a structured schema like this.
Problem
I'm looking for an way to configure a schema registry per API in one json-schema store. For example, I'm looking for a way to access the contents inside definitions
in two schema stores, https://json.schemastore.org/eslintrc.json
and https://json.schemastore.org/partial-eslint-plugins.json
.
import Ajv from 'ajv';
const ajv = new Ajv();
const [reply01, reply02] = await Promise.all([
fetch('https://json.schemastore.org/eslintrc.json', { method: 'GET' }),
fetch('https://json.schemastore.org/partial-eslint-plugins.json', {
method: 'GET',
}),
]);
const [resp01, resp02] = await Promise.all([reply01.json(), reply02.json()]);
ajv.addSchema(resp02);
ajv.addSchema(resp01);
const refs = [
'https://json.schemastore.org/eslintrc.json/definitions/stringOrStringArray',
'https://json.schemastore.org/eslintrc.json/#/definitions/stringOrStringArray',
'https://json.schemastore.org/eslintrc.json#/definitions/stringOrStringArray',
'#/definitions/stringOrStringArray',
'https://json.schemastore.org/partial-eslint-plugins.json/definitions/ruleNumber',
'https://json.schemastore.org/partial-eslint-plugins.json#/definitions/ruleNumber',
'https://json.schemastore.org/partial-eslint-plugins.json/ruleNumber',
]
const validators = refs.map((ref) => {
try {
const validator = ajv.compile({ $ref: ref, });
return validator
} catch (error) {
console.log(error);
return undefined;
}
});
Expectation
How do I access the above eslintrc.json/definitions
?
Environments
- Node v20.11.1
- AJV 8.12.0
- Reproducable Repo.
Hi @imjuni, after digging into the error messages when trying to load the refs (or actually I tested using ajv.getSchema as it was simpler) I found that the original schemas were not loading correctly because of missing formats that are being used in those schemas.
I fixed this by adding ajv-formats
to the example.
import Ajv from 'ajv';
import addFormats from "ajv-formats";
const ajv = new Ajv();
addFormats(ajv);
From here you can see which of your ref syntax works properly.