Skip to content

Need more details of annotation collection #530

Closed
@handrews

Description

@handrews

There should be pseudocode and a sample/recommend output format, as there is with Hyper-Schema. This should include guidance on how annotation collection can be implemented as part of the same evaluation process as validation.

  • Should explain that annotations are dropped whenever a validation check fails; the lack of annotations from not and non-validating branches of oneOf, if, etc. is a natural consequence of that
  • Should cover how to indicate the schema from which the annotation was contributed- see example below for concerns around $ref
  • Should note that there are both static annotations (all of the ones in the validation spec) and dynamic annotations that change based on the instance's contents (links and base in the hyper-schema spec)
  • Should perhaps give some guidance around complex object annotations (e.g. links): how do they fit into the overall JSON Schema model? Are there any particular limitations?
  • Should provide guidance on whether keywords can only register annotations under the keyword name or can define different annotation names. The use case for different names would include defining an annotation to which multiple keywords contribute, and wanting to avoid associating the annotation with one specific keyword

Some of the above may get split out into their own issues.

The following example shows the motivation for indicating where we were in the schema when the annotation was contributed. A common request is to be able to figure out which title or description to use, with a typical desired heuristic is that values in parent schemas are preferred over values in child schemas. Note that "child" in this cases is what me might call the logical child, following $refs, instead of the physical child (a nested subschema within the current schema object).

So let's have a schema:

{
    "type": "object",
    "properties": {
        "foo": {
            "title": "Title adjacent to reference",
            "description": "Lots of text",
            "readOnly": true,
            "$ref": "#/definitions/fooDef"
        }
    },
    "definitions": {
        "fooDef": {
            "title": "Title in reference target",
            "description": "Even more text"
        }
    }
}

With an instance of:

{
    "foo": "whatever"
}

The annotation results might look like this (I literally made up how $ref appears in the JSON Pointer-ish thing while typing this example, so don't take that as set in stone):

{
    "/foo": {
        "title": {
            "/properties/foo/$ref/title": "Title in reference target",
            "/properties/foo/title": "Title adjacent to reference"
        },
        "description": {
            "/properties/foo/$ref/description": "Even more text",
            "/properties/foo/description": "Lots of text"
        },
        "readOnly": true
    }
}

"/foo" is the instance pointer- this is the place in the instance to which the annotations apply.

Under that, the property names are the names of each annotation. All of these are also the keyword names that produced them, but in theory you could do something that doesn't map directly (please allow me to wave my hands on that- it's related to a complicated proposal that's under discussion and may not end up being relevant).

Under each annotation, the format is determined by the annotation.

readOnly just has a boolean, because it's explicitly stated (as of draft-07) that the overall value of readOnly is a logical OR of all applicable values. So there's no need to keep track of which value came from where- just let the application know the final outcome.

On the other hand, the way "title" and "description" are shown here is probably the default behavior. For those, "/properties/foo/... are schema pointers, more or less. Pointing across $ref is a bit weird and I need to figure out if that's the right approach. But the idea is to be able to tell that one of those is a runtime-parent of the other, and allow applications to make a decision based on that.

It might be better to use an array of terms instead of a not-quite-JSON Pointer. And it's not yet clear to me whether the keyword itself should be at the end of the pointer-ish thing / array. That also has to do with how much we want to abstract away the keyword source of an annotation. In the case of something like title or readOnly, we really do just want literally what the keyword says.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clarificationItems that need to be clarified in the specificationcore

    Type

    No type

    Projects

    Status

    Closed

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions