Open jerstlouis opened 3 years ago
Venders who want to generate API libraries won't like that much =D
@Relequestual I believe it would technically be possible to generate API libraries for this, treating those templated parameters generitcally, and the library would need to fetch those schemas using references at run-time.
This allows for much more powerful/flexible APIs which work on multiple instances/deployments using the same templated API definition, and thus greatly increases interoperability.
Maybe. My response was a little throw-away. This repo is really a holding ground till groups of interested parties (including key vendors) can form a group to create vocabularies with agreed semantic meaning. Hopefully one day you'll be drawn back here with someone wanting to make this happen =]
@jerstlouis Thanks for writing up your thoughts.
We can't make changes to the $ref
keyword with a vocabulary because it's a core keyword. However, if you give it a different name such as templatedRef
, it can be defined in a vocabulary and implemented. If the vocabulary becomes popular, we might consider merging the templatedRef
functionality into $ref
.
Generally, implementing a new keyword should be easy, but this one probably won't be because it violates a core assumption in JSON Schema that there are only two kinds of things: schemas and instances. You have added a new kind of thing: template variables. Rather than just writing a plugin, you'll likely have to fork your favorite implementation and modify it (or write something from scratch).
But, first things first, your proposal needs more detail. Here are some things you will need to think about and address.
$ref
at the top level of the schema. Are templatedRef
s only allowed at the top level of the schema? Probably not.templatedRef
s in a schema resolved against the same template variables?templatedRef
s in referenced schemas resolve against the template variables as well?templatedRef
in a referenced schema has a template name collision with a templatedRef
in the original schema? Is there a way to disambiguate?templatedRef
is encountered and the necessary template variables aren't given? Is it an error? Does it do a best effort and continue?@jdesrosiers Thank you very much for proposing a way to move this forward.
{identifier}
).$templatedRef
could be allowed at any level, however I think even having it only at the top-level would allow to implement the use cases we are thinking of, which is mainly to specify a unique schema for OpenAPI path parameters, which depends on earlier path parameters. That is, being able to write:
"schema" : { "$templatedRef" : "./api/collections-styles/{collectionId}" }
instead of
"schema" : { "type" : "string" }
directly in the properties of a definition for an OpenAPI components/parameters.templatedRef
s in a schema would be resolved against the same template variables.templatedRef
's in referenced schemas resolve against the same template variables -- all template variables required for a schema being referenced, including any nested use of template variables, would be provided. But for our use cases, just being able to use a $templatedRef
to reference one schema which would not need to support $templatedRef
would be enough. My initial understanding (which might be wrong, see below) was that JSON Schema needs to support this because the "schema"
property itself is defined as being of a JSON Schema type, therefore the "$ref"/$"templatedRef
logic needs to be supported by JSON Schema. Although looking at https://swagger.io/specification/#schema-object , the Schema Object is being defined as an "extended subset", and the Reference Object, is something else entirely, so potentially one OpenAPI extension could be the support for $templatedRef
?I am realizing that really what needs to be extended is probably the OpenAPI Reference Object or the JSON Reference, rather than JSON Schema, from https://swagger.io/specification/ :
The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.
For this specification, reference resolution is accomplished as defined by the JSON Reference specification
and not by the JSON Schema specification.
Thank you!
As discussed in https://github.com/json-schema-org/json-schema-vocabularies/issues/35#issuecomment-767624829 , in a context of using JSON Schema in an OpenAPI definition, I suggested the possibility to use templated path parameters in "$ref", to allow validation of later path parameters based on dynamic schemas that could be retrieved by substituting the templates by the selected value for earlier path parameters.
The resolved "$ref" would become regular "$ref", but in OpenAPI definitions one could write e.g.
"$ref" : "./api/collections-styles/{collectionId}"
and before the final validation step, the
{collectionId}
template would be replaced by a selected value likecollection1
. (e.g. in this example, this "$ref" is used to define the valid values for{styleId}
in a path/collections/{collectionId}/styles/{styleId}
).The
{collectionId}
would have previously been validated against another potentially dynamic list like"$ref" : "./api/collections"
../api/collections
would return something like:and
./api/collection-styles/collection1
would return something likewhile
./api/collection-styles/collection2
would return something likeThe context being that available/compatibles styles depend on the selected collection.
One simple way to implement this would be to have a validating function for such schemas which accepts a dictionary of template parameters / values, allowing to resolve all the templated
$ref
.