Open MikeRalphson opened 6 years ago
This also raises the question: what is a "root schema"? The term is not defined elsewhere in the spec.
Given this fragment:
components:
schemas:
container:
type: object
properties:
value:
$ref: "#/components/schemas/value"
value:
type: object
xml:
name: errorValue
properties:
error:
type: string
Is this allowed or prohibited (i.e. is value
a "root schema")? Does value
become a "root schema" if it is directly referenced (not from within a properties
property?
Agree with @MikeRalphson. We can define the root schema as the first one "hanging" from a, for instance, Media Type Object schema property.
Given that schemas are reusable pieces, what is a root schema in one place will probably not be in another place. An example:
paths:
/container:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/container' # Here "value" is not root
/value:
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/value' # Here "value" is root
components:
schemas:
container:
type: object
properties:
value:
$ref: "#/components/schemas/value"
value:
type: object
xml:
name: errorValue
properties:
error:
type: string
So, from the schema perspective, there's no way to know if it will be root or not because there's no information about its context (and I think there should not be, to make them more reusable). This reminds me of the required
property. It is defined in the parent schema because in some places it will be required and in some others, it will not.
components:
schemas:
container:
type: object
required:
- somethingRequired
properties:
somethingRequired:
type: string
I second that. The xml
code generation hints must be available on the top level entities representing data types, and not just on the property level. Otherwise, one cannot customise the generated code.
And I would rather see this to be a part of the OAS 3.0.0 instead of some future release as it is currently being supported by Swagger 2.0 and we cannot migrate from that to OAS 3.0.0 without this feature.
And, according to the OP @MikeRalphson, OAS3 should differentiate between xml
code generation hints on top level data types, items
of array
S and other properties.
Example
definitions:
xml:
type: object
properties:
name:
type: string
namespace:
type: string
prefix:
type: string
xmlOnProperty:
allOf:
- ./definitions/xml
- type: object
properties:
attribute:
type: boolean
default: false
wrapped:
type: boolean
default: false
@MikeRalphson JSON Schema 2019-09 has definitions for "schema document", "schema resource", "root schema", "schema object", and "subschema". It shouldn't be too hard to adapt that for the OAS situation of schema objects embedded in a non-schema document.
It is helpful to be aware of the analogies between JSON Schema and XSD. What seems to be called here a "root schema" (if I understand the comments correctly) is named schemas, that is, the schemas contained by /components/schemas (V3) or /definitions (V2). They are equivalent to a named type definition in XSD. Such a type definition is used by element declarations or attribute declarations. The name of the item (corresponding to a JSON property name) is NEVER assigned by the type definition, always by the element/attribute declaration. These declarations are equivalent to the fields in a properties
object. Like the name, also cardinality constraints can only be placed in those declarations, never in the types. Cardinality constraints are roughly equivalent to "required", @fmvilas - hence we only have to look at XSD and understand the equivalences in order to have a clear idea what belongs where. (Not that we could not do it differently, but we should think very carefully before doing it, and be aware of the deliberate deviation.)
And because of this analogy, it makes sense to me to keep the xml
keyword out of "root schemas" = named schemas (alias type definitions): property naming is not the business of the type used to constrain the property value. Arguments in favor of allowing xml
there in the interest of code generation should be reviewed crititically - they would have to be very convincing.
There is a real issue with translation into XML, which is the necessity to insert an XML root node, for which there is no correspondence in JSON. Currently, OAS foresees no possibility to control the invented name, leaving the integration developer in the lurch.
@OAI/tsc review request: Should we add support for this, or does the following example indicate that it's actually supposed to be supported already for named Components?
4.7.26.2.3 XML Attribute, Prefix and Namespace
In this example, a full model definition is shown.
Person:
type: object
properties:
id:
type: integer
format: int32
xml:
attribute: true
name:
type: string
xml:
namespace: http://example.com/schema/sample
prefix: sample
<Person id="123">
<sample:name xmlns:sample="http://example.com/schema/sample">example</sample:name>
</Person>
The "full model" comment seems to contrast with the intro text of the whole series of XML examples:
The examples of the XML object definitions are included inside a property definition of a Schema Object with a sample of the XML representation of it.
But this "full model" example uses what looks like the name under #/components/schemas
as the root XML element. Which does not rely on the xml
keyword being used at the root.
Is this the intended solution?
I'm in support of making OpenAPI more useful for those using XML format, and I think Mike's original suggestion of allowing xml in a root schema to support a name property, but disallowing some of its properties in that context is a sensible way to proceed.
I don't have the bandwidth to drive those changes, but I suggest we leave the issue open as an invitation for that contribution if anyone would like to make it.
@lornajane I've added it to the 3.2 milestone to indicate that we'd like to do it. We can always punt it out of that milestone if it does not fit or no one volunteers to do it.
While investigating the background for PR #4126 , I noticed this again.
Taking a look at the OAS 2.0 XML Object provides strong evidence that there is not actually a gap here, and that the name of the root element was intended to come from the schema name in the Components Object, as I previously speculated.
The key to understanding this is the word "model", which appears in a few places, starting with the first line of the XML Object section:
A metadata object that allows for more fine-tuned XML model definitions.
and then in the XML Attribute, Prefix and Namespace subsection of XML Object Examples:
In this example, a full model definition is shown.
The "full model definition" (in YAML) looks like:
Person:
type: object
properties:
id:
type: integer
format: int32
xml:
attribute: true
name:
type: string
xml:
namespace: https://example.com/schema/sample
prefix: sample
corresponding to:
<Person id="123">
<sample:name xmlns:sample="https://example.com/schema/sample">example</sample:name>
</Person>
Everything I've quoted above appears in 2.0, 3.0, and 3.1, with the only variation being that 2.0 used swagger.io instead of example.com, and 3.1 uses https
instead of http
in the earlier versions.
So what's going on here?
OAS 2.0 used the term "model" very specifically, which is illustrated by the explanation of discriminator
:
The value of the chosen property has to be the friendly name given to the model under the definitions property. As such, inline schema definitions, which do not have a given id, cannot be used in polymorphism.
The Definitions Object, the precursor of the schemas
field of the 3.x Components Object, is introduced as:
An object to hold data types that can be consumed and produced by operations. These data types can be primitives, arrays or models.
This tells us that "models" specifically refers to type: object
schemas. And if one looks at the example section headings under the Schema Object in 2.0, 3.0, and 3.1, the term "Model" is used in all object schema example titles, while the first example (a type: string
schema) is titled "Primitive Sample".
This means that in 2.0 it is explicitly clear from the example and the use of the term "model" that the root element name is taken from the "model name", meaning the name under the definitions
field.
This is clearly still the intent in 3.x, but the text was not updated to replace the word "model" with "schema component" or similar.
There is no need for a new field in the XML Object for this. The only change that needs to be made is to update the text to match 3.x terminology, which was no doubt missed as the XML Object section hasn't really changed since 2.0 (except for the easy search-and-replace swagger.io
and http:
changes).
We can pick this up and improve the wording around the root element by describing the structure as being a component schema rather than a model definition.
This is a question about the specification, and the intent of the following description in the Schema Object, relating to the
xml
property:This has the effect of banning the construct
As a point-of-reference only, both
swagger-ui
andswagger-editor
appear to honour this (useful) construct.Is it possible to align the specification with real-world use for this case, and possibly move the restriction on
xml
properties on root schemas to those sub-properties (such asattribute
andwrapped
) where it seems to make sense?