I used to validate the response body against the piece of the OpenAPI schema (I parsed the schema file and took only the needed response schema).
But when the response schema references another components schema (from the same file) - it won't work. I've read this doc about combining schemas: https://ajv.js.org/guide/combining-schemas.html
But it's not clear how to work with multiple references/schemas.
It looks like the "ajv" library cannot work with the whole OpenAPI schema object: (Error: strict mode: unknown keyword: "openapi")
.
Is the whole OpenAPI schema validation possible at all? How do I combine more than 2 schemas (if there are many references)?
Currently I'm trying to combine at least 2 schemas and I'm getting the resolve reference error:
can't resolve reference testObject.json#/schemas/testObject from id http://example.com/schemas/searchResults.json
Here's my test file (it's a piece of the OpenAPI to test only this specific reference case):
## test.spec.yaml
schemas:
testObject:
$id: http://example.com/schemas/testObject.json
type: object
properties:
prop1:
type: string
searchResults:
$id: http://example.com/schemas/searchResults.json
type: object
properties:
testObjects:
type: array
items:
$ref: "testObject.json#/schemas/testObject"
Here's my code:
import * as fs from "fs";
import Ajv from "ajv";
import * as yaml from "js-yaml";
describe("test", () => {
it("should validate the openapi schema", async () => {
const schema: any = yaml.load(fs.readFileSync("test.spec.yaml", "utf8"));
const a = schema.schemas.searchResults;
const b = schema.schemas.testObject;
const ajv = new Ajv({
strict: true,
allErrors: true,
verbose: false,
schemas: [a, b],
});
const validate: any = ajv.getSchema(
"http://example.com/schemas/searchResults.json"
);
const valid = validate({ testObjects: "foo" });
if (!valid) throw new Error(JSON.stringify(validate.errors));
});
});
Ok, after some investigation I realized the ajv doesn't work with openapi schema format and it needs some efforts to prepare JSONs out of OpenApi schemas which might be tricky when it comes to working with refs and nesting.
As for my example, there were 2 issues:
$ref: "testObject.json#/schemas/testObject"
-> incorrect. It should be something like "testObject.json#/definitionId"
const testObject = {
$id: "http://example.com/schemas/testObject.json",
definitions: {
int: {type: "integer"},
str: {type: "string"},
},
}
So I can refer to the exact object, like this:
$ref: "testObject.json#/definitions/int"