Skip to content

Handle subschemas with both "definitions" and "type" #52

Open
@dragonwasrobot

Description

@dragonwasrobot

Currently, we don't recognise subschemas which may contain both a "definitions" property and a "type" property. The current assumption is that all definitions are contained in the "definitions" property of the root schema, which might be nested, while we should probably aim for something more generic that can parse arbitrarily nested schemas found in "definitions" and maybe also in the "properties" property of the root schema. First step is to check the JSON schema spec to find out exactly where "definitions" properties can be expected.

From discussion in #51
"""
In JS2E.Parsers.Util.determine_node_parser/3 there is a list of predicate functions:

predicate_node_type_pairs = [
{&AllOfParser.type?/1, &AllOfParser.parse/5},
{&AnyOfParser.type?/1, &AnyOfParser.parse/5},
{&ArrayParser.type?/1, &ArrayParser.parse/5},
{&DefinitionsParser.type?/1, &DefinitionsParser.parse/5}, // <-- the bad guy
{&EnumParser.type?/1, &EnumParser.parse/5},
{&ObjectParser.type?/1, &ObjectParser.parse/5},
{&OneOfParser.type?/1, &OneOfParser.parse/5},
{&PrimitiveParser.type?/1, &PrimitiveParser.parse/5},
{&TupleParser.type?/1, &TupleParser.parse/5},
{&TypeReferenceParser.type?/1, &TypeReferenceParser.parse/5},
{&UnionParser.type?/1, &UnionParser.parse/5}
]
which is used to determine what parser to call given a node object.

So when we parse a root node that contains both a "properties" and "definitions" property the following calls happen:
RootParser.ex::parse_schema/2 -> RootParser.ex::parse_root_object/3 -> Util.parse_type/4 -> Util.determine_node_parser/3 which calls DefinitionsParser.type? that looks like this:

def type?(%{"definitions" => definitions})
when is_map(definitions), do: true
def type?(_schema_node), do: false
which returns true, thus it never hits the ObjectParser.type?.

Since there is an example in the spec of nested "definitions" properties: http://json-schema.org/latest/json-schema-core.html#id-keyword - which means that a nested schema can probably also contain both "properties" and "definitions" on the same node.

Noting that "definitions" is a bit of a special case compared to the other node types, since it can co-exist with other node types on the same node (if that makes sense), it should probably be moved out of determine_node_parser and into parse_type such that parse_type checks each node if it also has a definitions property. While this sounds pretty straight forward to fix it does create a few too many extra checks to my liking.
"""

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions