I am getting an error when using Ajv to load a schema that uses $ref
imported from a yaml
file inside an OpenAPI description.
This is my yaml
file:
openapi: 3.0.3
info:
title: Demo
version: 1.0.0
paths:
/carousel:
get:
responses:
"200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/test"
components:
schemas:
other:
type: object
properties:
component:
type: object
test:
type: object
properties:
slides:
type: array
items:
type: object
properties:
contents:
type: array
items:
anyOf:
- $ref: "#/components/schemas/other"
This is my code (JS + Vite)
import Ajv from 'ajv'
import YamlContent from '../Config/API.yaml'; //vite.config.js with package @modyfi/vite-plugin-yaml
const validate =
new Ajv({
schemas: YamlContent.components.schemas
}).
getSchema(YamlContent.components.schemas.test);
I also tried:
const validate =
new Ajv().
addSchema(YamlContent.components.schemas.other).
compile(YamlContent.components.schemas.test);
But it always gives the same error. What am i missing here? Thanks.
no reason to use anyOf
for a single schema, just pass that schema as the reference
openapi: 3.0.3
info:
title: Demo
version: 1.0.0
paths:
/carousel:
get:
responses:
"200":
description: Successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/test"
components:
schemas:
other:
type: object
properties:
component:
type: object
test:
type: object
properties:
slides:
type: array
items:
type: object
properties:
contents:
type: array
items:
$ref: "#/components/schemas/other"
OpenAPI 3.0.x requires the use of ajv-draft-04
and the ajv-formats
packages.
Because you are using a yaml file, you need a way to load it with js-yaml
{
"dependencies": {
"ajv": "^8",
"ajv-draft-04": "^1.0.0",
"js-yaml": "^4.1.0",
"ajv-formats": "^2.1.1"
}
}
We use strict:false
to make sure the ajv validator abides by the JSON Schema specification correctly.
The idea is to use the addSchema()
method to add the entire OpenAPI description; then use the validate
function and provide an object schema with a $ref
to the component schema you want to validate against in the first argument and pass the data instance as the second argument.
Then output the results.
const Ajv = require('ajv-draft-04')
const addFormats = require('ajv-formats')
const fs = require('fs')
const { load } = require('js-yaml')
const openapiDescription = load(fs.readFileSync('./Config/API.yaml'))
const testData = {
"slides": [
{
"contents":
[{ "component": {} }]
}]
}
try {
const ajv = new Ajv({ strict: false })
addFormats(ajv)
ajv.addSchema(openapiDescription, "API.yaml")
let validate = ajv.validate({ "$ref": "API.yaml#/components/schemas/test" }, testData)
console.log({
valid: validate,
error: ajv.errorsText(validate.errors)
})
}
catch (error) {
console.error(error.message)
}