karenetheridge / JSON-Schema-Modern

Validate data against a schema using a JSON Schema
https://metacpan.org/release/JSON-Schema-Modern/
Other
10 stars 1 forks source link

OpenAPI document support #43

Closed karenetheridge closed 2 years ago

karenetheridge commented 3 years ago

OpenAPI schemas contain keywords such as components which contain standard json schemas beneath them. If we hand such a document to the evaluator today, it will not have its subschemas examined, because of the lack of recognition of these keywords and an understanding of the necessity to parse properties beneath them.

This is okay if the subschemas are simple, as code can simply extract the part of the document that contains real json schemas and then pass them to the evaluator directly. However, if a schema contains a reference to another part of the document (for example, "$ref": "#/components/schemas/ShapeInterface", then there is a problem as that reference will not be found, due to the root document (with URI "") not having been indexed.

We need to be able to pass an entire OpenAPI document to ..::Document->new and have its subschemas traversed using correct addressing so that references will work properly.

(The fact that OpenAPI introduces new keywords such as discriminator which have their own validation logic is another issue entirely and will require additional code support, and can be addressed separately.)

karenetheridge commented 3 years ago

we'll need a new Document type to hold openapi documents (?), and then some baked-in logic to under the openapi document layout so the schema data can be properly traversed.

karenetheridge commented 3 years ago

see https://github.com/OAI/OpenAPI-Specification/pull/2467 for the new metaschema and vocabulary, and https://github.com/OAI/OpenAPI-Specification/pull/2474 for the schema describing the entire OpenAPI document (which is not a schema in itself but has embedded schemas that must be indexed for URIs, within the context of the entire document).

karenetheridge commented 3 years ago

There are also some additional formats which should be plugged in, and not all of them are for the string type: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#data-types

karenetheridge commented 3 years ago

Another option for parsing OpenAPI documents that are not themselves JSON Schemas, other than baking in logic to traverse all the non-schema keywords in order to find the embedded schemas: Use the OpenAPI document schema itself (https://github.com/OAI/OpenAPI-Specification/pull/2474) as a way to bootstrap the traversal process... various options exist:

  1. instead of passing the entire document to traverse(), validate it against its schema... during validation we would need to recognize the presence of embedded schemas and then can pass those subschemas off to traverse() for indexing of contained URI resources. Note that no reliable mechanism yet exists for detecting embedded schemas; perhaps a keyword could be introduced to mark its presence -- that is, a keyword in the document's schema, not the document itself. Right now we would have to use heuristics like detecting the presence of a $dynamicAnchor keyword and "type":["object","boolean"] which are likely indicators of a schema.

  2. a tiny bit of custom code, less generic than option 1 above, but requiring less code than baking in knowledge of the entire OpenAPI document... knowing that embedded schemas only exist in OpenAPI documents where $ref: '#Schema' occurs, use that as a trigger for subschema detection. This is more generic than having to remember every path where a schema might occur.

karenetheridge commented 3 years ago

The openapi metaschema (dialect) is https://spec.openapis.org/oas/3.1/dialect/base. It is the same as the base draft2020-12 dialect, except with the addition of https://spec.openapis.org/oas/3.1/vocab/base (which defines the keywords 'xml', 'externalDocs', 'discriminator' and 'example').

karenetheridge commented 2 years ago

This is now in the bailiwick of JSON::Schema::Modern::Document::OpenAPI.