Skip to content

Restructuring of output formatting #973

Closed
@gregsdennis

Description

@gregsdennis

While writing Section 10 on output, I was implementing the formatting in my library, Manatee.Json. In that library, I don't collect annotations in the same way as described in the spec. As a result the annotation output of a successful validation was not fully explored.

I have recently been working on a new validator that does follow the recommendations of the spec in regard to annotation collection and have reached the same questions that many other implementors have asked me regarding annotations in the output format, to which I naively responded that annotation output is analogous to error output.

I aim to fix this. This issue is a compilation of questions and issues I've experienced trying to reimplement output formatting as well as potential solutions to some of them.

1. Annotations vs Nested Results

With the current output, annotations are to be represented as their own output unit within the annotations collection, including the valid property and all JSON pointers indicating where the annotation came from and to what part of the instance it applies. Additionally, any nested results were also to be in this array. This conflates annotations with nested results and the only way to identify which were annotations and which were nested results was via the location properties.

To resolve this, we should split these collections. Nested results should remain as they are, but the property name needs to change.

The proposed fix adds (or hijacks, rather) a single property, annotations to the output unit. It's only present for valid = true and when there are annotations (no empty arrays). The value is an array of all annotations for this node.

For instance, properties requires that it adds the names of any validated properties as annotations. To this end, the annotations on the properties node will be an array of these property names.

{
    "valid": true,
    "keywordLocation": "#/properties",
    "instanceLocation": "#",
    "annotation": [
        "foo",
        "bar"
    ]
}

I'm not sure how this fits in with collecting unknown keywords as annotations since that would effectively require a node for each unknown keyword, but maybe that's fine (the location pointer would indicate the keyword, and the annotation value would be the unknown keyword's value).

This idea also may invert the intent behind dropping combining annotations, but I haven't thought through that completely, yet.

This is also in line with @ssilverman's comment regarding how his implementation handles annotations internally. (My new validator uses a similar mechanism.)

2. Nested Nodes

Having the nested result nodes under annotations for validated results and errors for invalidated results was, admittedly, me trying to be clever about things. Practically, it's difficult to deal with.

The proposal here is to have these always under a consistent name, e.g. nested, results, etc. I'm not too fussed about what the name is, but it should always be that regardless of the value of valid.

3. Too Many Secrets Nodes

In trying to pare down the list of nodes for the detailed and basic formats, I found that a lot of nodes were kept that may not be necessary.

For example, in an error scenario, is it necessary to list passing subschemas of an allOf? To a person just trying to figure out what's wrong, these are just noise to be filtered out in order to pinpoint the one subschema that failed.

The algorithm for reducing returned values could be adjusted, and maybe needs to be dynamic based on the scenario. Maybe if a schema is valid, I don't care about any of the details and I just want a ✔️. But for failures I want to know only those nodes that failed, but I want detailed info about them, and maybe in a format that mimicks the schema (as detailed is intended to do). The current formats (and the algorithms to generate them) do not support this.

(Fake internet points for anyone who gets my reference in the title of this section.)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Closed

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions