santhosh-tekuri/jsonschema

Compiling a subresource with an extension validates the subresource against the root extension schema.

Closed this issue · 6 comments

I'm attempting to parse OpenAPI 3.1 specifications and I can validate the root of the document without issue, but I'm trying to process individual JSON schemas within the spec independently and I'm running into trouble.

This is a loose copy of what I'm trying to do:

comp := jsonschema.NewCompiler()

if err := comp.AddResource("https://spec.openapis.org/oas/3.1/schema/2022-10-07", oas31Reader); err != nil {
	return nil, err
}

oas31Schema, err := comp.Compile("https://spec.openapis.org/oas/3.1/schema/2022-10-07")
if err != nil {
	return nil, err
}

comp.RegisterExtension("openapi_3.1", oas31Schema, &oas3SchemaCompiler{})

if err := comp.AddResource("my-openapi-spec", in); err != nil {
	return nil, err
}

fullSpec, err := jsonschemaCompiler.Compile("my-openapi-spec")
if err != nil {
	return nil, err
}

// everything fine so far

subSchema, err := jsonschemaCompiler.Compile(fmt.Sprintf("%s#/components/schemas/Foo", "my-openapi-spec"))
if err != nil {
        // bang! this breaks here
	return nil, err
}

I get the message that #/components/schemas/Foo does not have required properties "openapi" and "info".

It appears that in Compiler.validateSchema() we range over all the extensions on the compiler and validate that the current doc is valid according to that extension. This is fine, except I need it to validate based on the current vloc, and not on the root of the extension schema.

I'm still trying to get to grips with how the library is implemented, but it could also be an issue in Schema.validate(), since it doesn't seem to take vloc into account.

Or, I could just be doing something wrong, any help would be appreciated!

If you can share the complete source code, and some example of what your extension is trying to do, then it would help me understand your issue.

I've created a fork and committed an example you can run with go test, see openapi_test.go:

https://github.com/dan-j/santhosh-tekuri-jsonschema/tree/142-extension-subschema-validation

Updated with some comments ^

I had a look at your source code; it seems you got confused "what is meant by extension"

openapi document is a json document. and its jsonschema is openapi_3.1.schema.json (note that you are confused that openapi_3.1.schema.json is the schema of extension. no it is not)

openapi uses jsonschema to specify schema for request and responses. but in addition to standard jsonschema it includes few additional keywords discriminator, xml, externalDocs and example (see Fixed Fields section in https://spec.openapis.org/oas/v3.1.0#schema-object)

among the above 4 keywords, only discriminator effects validation. rest of them are just for documentation purpose

so you have to write an extension for discriminator keyword. and the schema for this is at https://spec.openapis.org/oas/3.1/meta/base


now if you want to understand why you are getting validation error in your specific implementation:
you created an extension whose schema is openapi_3.1.schema.json. and openapi_3.1.schema.json says, openapi and info are required. So when you use this extension you are saying: I am introducing two new keywords openapi and info which are mandatory. So you are getting validation errors in schema compilation.

Ahh ok. So I was under the impression that extensions would only be applied if the ExtCompiler returned an ExtSchema, which for the full spec, it contains "openapi" so I return a noop schema, but for others I am returning nil.

I'm going to close this, thanks for your response!

extensions are always applied.

that mean your schema must be valid against all the registered extensions.
the extension.validate implement should look for its keywords and do the validation logic