[2.0.0 REVIEW] Clarify usage of JSON References (/Pointers) for non-JSON data structures
- Dominant language
- JavaScript
- Stars
- 5.3k
- Forks
- 382
- Avg merge
- 7m
- Merged PRs (30d)
- 4
Description
The introduction of [`schemaFormat` in Message Object](https://github.com/asyncapi/asyncapi/blob/master/versions/next/asyncapi.md#message-object) adds support for schema languages other than JSON Schema. The `$ref`erencing mechanism however was designed to only support JSON data structures as it [explicitly mentions](https://github.com/asyncapi/asyncapi/blob/master/versions/next/asyncapi.md#reference-object) the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) mechanism. So this needs additional clarification.
To be clear, any schema languages which underlying format is JSON (E.g. Avro) is not of concern. Schema languages which underlying format is YAML (E.g. RAML DataType, OpenAPI in YAML) are of lesser concern because simple wording could be added to the effect that a JSON Reference can be made to the JSON-equivalent of the YAML-formatted schema.
One could always “come-up” with some meaning around what comes after `#` for non-JSON formatted schemas. However, the lack of explicit definition of what it means to use a JSON Reference/Pointer to refer to non-JSON data structures would leave things up to interpretation, and as a result may introduce a divergence of behaviors across tools supporting the AsyncAPI Spec.
Let’s take Protobuf for example. What happens when there are nested types and I want to refer to a type within a nesting?
E.g.
```
# Foo.proto
message Foo {
message Bar {
string name = 1;
}
}
```
How do I refer to `Bar`? Is it`Foo.proto#/Foo/Bar` or `Foo.proto#/Foo.Bar`? The former looks more “right” to me, however one could make a case that `Foo.Bar` is how one would refer to Bar from within Protobuf and therefor is the way it should be referred to in the Pointer. Since a Protobuff document is not a JSON data structure, there is nothing to contradict this argument.
It would be interesting to take protobuff and maybe one more -- say XSD -- and think of all the corner cases, probably by going over the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) and [JSON Pointer](https://tools.ietf.org/html/rfc6901) specs and attempt to apply each rule to both schema language. If any of those rules are contentious or may leave room for interpretation, then we should think of some wording to add to the AsyncAPI 2.0 spec. Another solution could be to have some kind of registry or mini-spec for each schema languages and have the rules defined there.
IMO, a much (much!) simpler -- and arguably better -- solution would be to restrict the use of JSON Reference to JSON and YAML -formatted schemas. We would say something along the lines of:
> The Reference Object SHALL either be a URI or a JSON Reference. A JSON Reference is comprised of a URI followed by an optional JSON Pointer as described in [this draft](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03). A JSON Reference SHALL only be used to refer to a schema that is formatted in either JSON or YAML. In the case of a YAML-formatted Schema, the JSON Reference SHALL be applied to the JSON representation of that schema. The JSON representation SHALL be made by applying the conversion described [here](https://tbd...).
To sum-up:
1. clarify how `$ref` can be applied to YAML data structures
2. refer to an existing mechanism used to translate YAML to JSON
3. clarify referencing mechanism for any non-JSON and non-YAML schema languages
Contributor guide
Assessment
This issue has not been assessed yet.