Closed RomanHotsiy closed 6 months ago
@RomanHotsiy the 3 options have been grating a little with me too. I'm already thinking of consolidating Reusable Parameter Object
into Reusable Object
and only allow value overrides where the referenced object is a Parameter Object.
I can bite the bullet and rename name
to reference
too as part of the same effort. This was a mediocre attempt to stay even further away from a clash, but I now think that clear explaining how you reference a JSON Schema object versus a non JSON Schema object is clearer (also helped by just having two mechanisms rather than 3)
Removing the keyword clash with JSON Schema's $ref is indeed the primary motivation. There's a whole world of pain caused by this as well as real inabilities to adequately resolve references based on lack of clarity on how to deal with different JSON Schema versions in referenced fragments as well as dealing with the direction of resolution and upgrading or downgrading accordingly. It's completely left up to an implementor to decide which results in interoperability issues.
The same mantra of moving away from the current OAS Reference Object (which contains the keyword clash) is also being proposed for the next version of OAS.
@RomanHotsiy - hopefully #182 simplifies the situation
@frankkilcommins this makes it better for sure! Thanks.
Yet I'm still confused why we have to invent a new way of reuse just for this spec. Whatever reusability mechanism is planned for Moonwalk it seems to be different form this.
So instead of a single reusability mechanism ($ref) we're inventing new ones for each spec.
I understand this is part of a broader discussion about $ref
's semantics.
@RomanHotsiy the Moonwalk discussion isn't settled yet, and I'm paying attention to how this works out as we try to figure that out.
So instead of a single reusability mechanism ($ref) we're inventing new ones for each spec.
Because we don't have a single re-usability mechanism. We have at least 9 across 3.0 and 3.1 (6 in 3.0, 8 in 3.1, 5 overlapping):
$ref
(URI-reference, replaces context with target, ignores all adjacent properties)$ref
(URI-reference, combines the target with the context, as long as no adjacent context properties conflict with target properties, otherwise the behavior is undefined)$ref
(URI-reference, overrides target summary
and description
with context fields if present and replaces the context with the result; all other adjacent properties ignored)$ref
(URI-reference, delegates to the target for the evaluation result, which is combined with adjacent keywords the same way as all other JSON Schema keywords)$dynamicRef
(URI-reference with complex runtime resolution, otherwise delgates as Schema Object $ref
)operationRef
(URI-refernce, delegates to the target, mutually exclusive with operationId
, does not otherwise interact with adjacent keywords)operationId
(identifier searched across all Operation Objects in the API Description's scope, which can be ambigusous so there's a recommendation to avoid certain scenarios; delegates to the target, mutually exclusive with operationRef
, but no other interactions with adjacent keywords)mapping
(URI-reference OR component name, delegates to the named/referenced component, no interaction with adjacent keywords)There are also numerous features that have implicit correlations - path or server template variables names, jsonSchemaDialect
setting the default $schema
, and probably other things I'm forgetting (the OASComply reports directory should have the complete taxonomy).
EDIT: And the way Server Objects get looked up across Operation, Path Item, and the root Object, which, like the component name connections, becomes ambiguous if you reference a complete document that has its own Components Object and/or root-level Servers Object).
LATER EDIT: Oh and the way tags
can optionally connect to Tag Objects
This is not even getting into the fact that some of those linkages that use URI-references resolve as URLs (strictly location-based) and some in 3.1 resolve as URIs (identifiers that need not correlate to location).
Plus, tooling support for $ref
in any form is egregiously inconsistent, and often outright incorrect. Too many tools refuse to process it, or refuse all but a few uses, or require its removal by a preprocessor. It's not like it's a system with good interoperability and consistent support. Nor does $ref
meet the intuitive expectations of the many users who expect it to do some sort of merge, which none of the variations do.
$ref
, with it's variable behavior and inconsistent support, is a huge pain point for consulting clients of mine that are trying to implement large-scale re-use across multiple providers. It's just not sufficiently interoperable or reliable, and the variations are too hard to understand. Workflows is specifically intended to span multiple API providers, and is likely to run into these problems. Without doing this, it was going to introduce at least one more $ref
variation to that poorly-supported tangle of variations. Having recently implemented all forms of referencing (by URI-reference or component name or operationId) in both 3.0 and 3.1, throwing more complexity onto that fire really does not feel like a win to me.
After reviewing the last draft of the spec I noticed there are 3 different ways to reference reusable components:
$ref
for inputsWe believe that the end users (authors) will be constantly confused about which to use in which context.
What problem do we solve with those 3 ways of referencing and why we can't use
$ref
s for all of those (which users are familiar with as well as tooling support).I believe it has to do with $ref semantics in context of JSON schema. I believe while it may improve the experience for tooling authors it makes it much worse for the end users.
But I'm not even sure if it makes it easier for the tooling authors as now we have to deal with more error messages and validations.
On a separate note I'm not clear why the Reusable objects has this specific structure:
The moment that I'm unclear about is why the field is called
name
while the expression does not resolve to the name or anything like name?