Because no specification is perfect, and OpenAPI certainly isn't, there are a number of compatibility issues that prance users have found. Here is some explanation and rationale of them.
Most of the issues stem from the fact that OpenAPI refers to JSON schema and related standards for its specification, but then subtly violates JSON schema or those other standards.
JSON only accepts string keys in objects. However, some keys in the specs tend to be integer values, most notably the status codes for responses. Strict mode rejects non-string keys; the default lenient mode accepts them.
Since the flex
validator is not based on JSON, it does not have this issue.
The strict
option therefore does not apply here.
The relevant parts of the RFC for JSON references can be condensed like this:
A JSON Reference is a JSON object, which contains a member named "$ref", which has a JSON string value. Example:
{ "$ref": "http://example.com/example.json#/foo/bar" }
(...)
Any members other than "$ref" in a JSON Reference object SHALL be ignored.
(...)
Resolution of a JSON Reference object SHOULD yield the referenced JSON value. Implementations MAY choose to replace the reference with the referenced value.
Prance is strict about ignoring additional keys, and does so by replacing the reference with the referenced value.
In practice, that means that given such a reference:
# main file
---
foo: bar
$ref: /path/to/ref
# and at /path/to/ref
---
baz: quux
Then, after resolution, the result is the following:
# resolved
---
baz: quux
That is, the key foo
is ignored as the specs require. That is the reason
the OpenAPI specs tend to use JSON references within schema
objects, and
place any other parameters as siblings of the schema
object.
Since JSON references can reference an object that references the first object, we can create recursive references. By default, when a recursion is detected, an exception is raised. There are two ways you can modify this behaviour:
- Increase the
recursion_limit
from it's default value of1
to some higher number. This doesn't actually help much on its own. - Set the
recursion_limit_handler
parameter to a callable. It accepts the recursion limit, the reference URL of the element being resolved, and the currently known recursions.
prance.util.resolver.default_reclimit_handler
is the default handler, and
will always raise an exception.
If the handler you set does not raise an exception, its return value is used
as the "resolved" value. To simply ignore recursions, use a handler that
returns None
- this will translate to the null value in the specs.
While OpenAPI specifies that $ref
is only to be interpreted as a
reference in specific places, the JSON specs say nothing of the sort. Since
most backends are based on JSON schema validators, prance simply treats all
occurrences of $ref
as references. This works well with the expecations of
JSON schema/JSON references, albeit not OpenAPI's interpretation of them.
This limitation is also not present in OpenAPI 2.0 specs. While those specs are older, they're still supported by prance. Compatibility between the interpretation of 2.0 vs. 3.0.0 is probably more user friendly than allowing $ref to be interpreted in different ways in different places, in violation of JSON reference specs.