Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Schema Object #894

Merged
merged 6 commits into from Feb 22, 2017
Merged

Update Schema Object #894

merged 6 commits into from Feb 22, 2017

Conversation

webron
Copy link
Member

@webron webron commented Feb 21, 2017

(This replaced PR #741)

Covers:

  • Clarifications about JSON Schema property adjustments to the OAS
  • Support for nullable
  • Support for writeOnly, removed required restriction
  • discriminator clarifications
  • examples cleanup


The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.
- type - Value MUST be a string. Multiple types via an array are not supported.
- allOf - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be:
"MUST be of a Schema Object or Schema Reference" ? (Ditto on the other items in the list.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please elaborate on what "not a standard JSON Schema." means. However, if it means "not a full JSON Schema but the OpenAPI Specification schema", I think we should just drop this since you already refer explicitly to [Schema Object](#schemaObject)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be the Schema Object, not Schema Reference (which I assume you meant JSON Reference). The Schema Object contains the JSON Reference in it.

The 'standard JSON Schema' is in reference to the initial point that the Schema Object is an extended subset of JSON Schema. I'd rather keep this explicit here due to questions raised in the past.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DavidBiesack I almost responded with a "+1" to your comment but I think the "Inline or referenced schema" as to being either a Schema Object or a JSON Reference to a Schema Object defined elsewhere. @webron's wording seem fine to me.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think "not a standard JSON Schema" may be confusing and not needed -- it just raises questions and distracts from the spec. Better IMHO would be to remove it or as @whitlockjc suggests, add "or a or a JSON Reference to a Schema Object" (I don't thing "defined elsewhere" is needed; that is implicit in being a JSON References - concise is better)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is useful to remind people that even when embedding schema objects in allOf what is being embedded is not a regular JSON Schema. I suspect many people don't realize that the schemas inside OpenAPI are not regular JSON Schemas.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't linking to a Schema Object do this?

versions/3.0.md Outdated
- oneOf - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.
- anyOf - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.
- not - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.
- items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema. `items` MUST be present of the `type` is `array`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "of the type" s/b "if the type"

versions/3.0.md Outdated
- items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema. `items` MUST be present of the `type` is `array`.
- properties - Property definitions MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- additionalProperties - Value can be boolean or object. If object, definition MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- $ref - As a [Reference Object](#referenceObject).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest change "As a Reference Object" to "A Reference Object"

- title
- description ([CommonMark syntax](http://spec.commonmark.org/) can be used for rich text representation)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove parens here (not used elsewhere in OAS when describing CommonMark)

versions/3.0.md Outdated
- properties - Property definitions MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- additionalProperties - Value can be boolean or object. If object, definition MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- $ref - As a [Reference Object](#referenceObject).
- description ([CommonMark syntax](http://spec.commonmark.org/) can be used for rich text representation).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove parens here (not used elsewhere in OAS when describing CommonMark)

@@ -2599,7 +2602,7 @@ definitions:
]
},
"Cat": {
"description": "A representation of a cat",
"description": "A representation of a cat. Note that `Cat` will be used as the discriminator value.",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an example:

Below are examples showing an array of Pet objects using petType as a discriminator:

- name: "Fluffy"
  petType: "Cat"
  huntingSkill: "lazy"
- name: "Rover"
  petType: "Dog"
  packSize: 6
[
  {
    "name" : "Fluffy",
    "petType" : "Cat",
    "huntingSkill" : "lazy"
  },
  {
    "name" : "Rover",
    "petType" : "Dog",
    "packSize" : 6
  }
]

@webron
Copy link
Member Author

webron commented Feb 21, 2017

Updates:

  • Updated JSON Schema support from Draft 04 to Draft 05 (or wright-00).
  • Following that, updated support for External references instead of Canonical dereferencing (same thing, different name).
  • Updated references to JSON Pointer.
  • Updated fallback of tools to deal with unknown formats.
  • Some wording updates.

Not included:

  • Updated example with discriminator value overriding. Pending review of the discriminator as a whole.

Let me know if I missed anything we discussed on the call today.

versions/3.0.md Outdated
Primitive data types in the OAS are based on the types supported by the [JSON-Schema Draft 4](http://json-schema.org/latest/json-schema-core.html#anchor8).
Models are described using the [Schema Object](#schemaObject) which is a subset of JSON Schema Draft 4.
Primitive data types in the OAS are based on the types supported by the [JSON-Schema Draft Wright 00](https://tools.ietf.org/html/draft-wright-json-schema-00#section-4.2) (also known as, JSON Schema Draft 05). Note that `integer` as a type is also supported and is defined as a JSON number without a fraction or exponent part. `null` is not supported as a value.
Models are described using the [Schema Object](#schemaObject) which is an extended subset of JSON Schema Draft 05.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it read better using "JSON-Schema Draft Wright 00" here since that is what you mentioned prior? Also, was hyphenating JSON Schema to JSON-Schema intentional in the link text? If so, what's the rules behind when we hyphenate and when we do not?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hyphen is a mistake. Will fix.

I can change it to JSON Schema Draft Wright 00 everywhere, but it's not the exact name. The exact name is draft-wright-json-schema-00 which is awkward to write across the doc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. I trust your judgement.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

versions/3.0.md Outdated
@@ -2214,8 +2215,8 @@ definitions:
A simple object to allow referencing other definitions in the specification.
It can be used to reference parameters and responses that are defined at the top level for reuse.

The Reference Object is a [JSON Reference](http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-02) that uses a [JSON Pointer](http://tools.ietf.org/html/rfc6901) as its value.
For this specification, only [canonical dereferencing](http://json-schema.org/latest/json-schema-core.html#anchor27) is supported.
The Reference Object is a [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) that uses a [JSON Pointer](http://tools.ietf.org/html/rfc6901) as its value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what's being said here. Is the Reference Object only for local references, as in references within the same document? If that's the case, the value is itself a JSON Pointer as a JSON Reference allows both local and remote references.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference Object is for all references whether local or remote.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I was hoping for. So in that case, the "that uses a JSON Pointer as its value" is not accurate is it? The JSON Pointer version of a $ref value is for local only and since a Reference Object is for local and remote references, isn't the Reference Object's $ref just a URI per the JSON References spec.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, @whitlockjc. The indication of JSON Pointer here is not needed. It was added in 2.0, back in the days where things were still unclear to us all. We now know better - A JSON References, is a JSON Reference, and in some cases the value is a JSON Pointer. The actual explanation here is wrong and unneeded. Will remove.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely reworked JSON Reference, see main comment.

@darrelmiller
Copy link
Member

:shipit:

- Removed hyphen
- Updated naming convention to reference only Wright Draft 00
- Simplified explanation of JSON Reference resolution
@webron
Copy link
Member Author

webron commented Feb 22, 2017

A few last minute updates to this PR:

  • Updated the naming of JSON Schema to be consistent throughout the doc.
  • Completely rewrote the Reference Object and updated its examples. I didn't realize the wording was relevant to the 2.0 but not 3.0. The wording should be simpler now, explain exactly what it is or isn't, and avoid the potential confusion regarding its resolution.

@tdc - please review again.

@darrelmiller
Copy link
Member

Yes, the wording is even better now. :shipit:

versions/3.0.md Outdated
- not - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.
- items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema. `items` MUST be present if the `type` is `array`.
- properties - Property definitions MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- additionalProperties - Value can be boolean or object. If object, definition MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be a JSON Reference to a Schema Object? If so, you might want to use similar wording like you did elsewhere.

versions/3.0.md Outdated
- items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema. `items` MUST be present if the `type` is `array`.
- properties - Property definitions MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- additionalProperties - Value can be boolean or object. If object, definition MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- $ref - A [Reference Object](#referenceObject).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, any place you could have a Schema Object you would allow a JSON Reference to a Schema Object but it is an either/or, as in you cannot mix a JSON Reference and a Schema Object in the same object. I think we could have some extra wording here making sure this is known to be the case, much like we document the items property as being applicable and required only when type: array.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about defining a section for OpenAPI Schema Definition and cite that in all these places where an inline or ref is allowed, and then define OpenAPI Schema Definition as exactly one of (inline) Schema Object or a JSON reference to a Schema Object

versions/3.0.md Outdated
- $ref - A [Reference Object](#referenceObject).
- description - [CommonMark syntax](http://spec.commonmark.org/) can be used for rich text representation.
- format - See [Data Type Formats](#dataTypeFormat) for further details. While relying on JSON Schema's defined formats, the OAS offers a few additional predefined formats.
- default - Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't specifically tell what the type is, or its purpose. Would it make sense to do this and then throw the existing content into a "(Note: ...)"?

@@ -2323,7 +2327,9 @@ While composition offers model extensibility, it does not imply a hierarchy betw
To support polymorphism, OpenAPI Specification adds the support of the `discriminator` field.
When used, the `discriminator` will be the name of the property used to decide which schema definition is used to validate the structure of the model.
As such, the `discriminator` field MUST be a required field.
The value of the chosen property has to be the friendly name given to the model under the `definitions` property.
There are are two ways to define the value of a discriminator for an inheriting instance.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without an example, this portion is unclear to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I might get this. Are you saying that the value of the discriminator field must match the name of a definition? Does this mean you can only use values that match keys of #/components/definitions?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point -- we rely heavily on external schema files via $ref. For example, if Cat and Dog are defined externally, I should still be able to use them. However for a schema included from an external schema.json there is no name as there is for one defined in /components/definitions. If all three schema (Pet, Cat, Doc) were defined externally (so that they can be used in multiple OpenAPI documents) and there is no single /components/definitions in which they reside, how would this work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll be handling the discriminator in a separate PR.

- clarified additionalProperties
- clarified default
- changed the definition of $ref

The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI Specification.
- type - Value MUST be a string. Multiple types via an array are not supported.
- allOf - Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think "not a standard JSON Schema" may be confusing and not needed -- it just raises questions and distracts from the spec. Better IMHO would be to remove it or as @whitlockjc suggests, add "or a or a JSON Reference to a Schema Object" (I don't thing "defined elsewhere" is needed; that is implicit in being a JSON References - concise is better)

versions/3.0.md Outdated
- items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a [Schema Object](#schemaObject) and not a standard JSON Schema. `items` MUST be present if the `type` is `array`.
- properties - Property definitions MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- additionalProperties - Value can be boolean or object. If object, definition MUST be a [Schema Object](#schemaObject) and not a standard JSON Schema (inline or referenced).
- $ref - A [Reference Object](#referenceObject).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about defining a section for OpenAPI Schema Definition and cite that in all these places where an inline or ref is allowed, and then define OpenAPI Schema Definition as exactly one of (inline) Schema Object or a JSON reference to a Schema Object

The value of the chosen property has to be the friendly name given to the model under the `definitions` property.
There are are two ways to define the value of a discriminator for an inheriting instance.
- Use the definition's name.
- Override the definition's name by overriding the property with a new value. If exists, this takes precedence over the definition's name.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this means. Override which property - the discriminator field (petType in this example)? If so, how is it overridden and specified? Would I do:

  Cat:  ## "Cat" will be used as the discriminator value
    description: A representation of a cat
    allOf:
    - $ref: '#/definitions/Pet'
    - type: object
      properties:
         petType:
              type: string
              enum:
              - Cat
          huntingSkill:
             ...

An example would help.

@@ -2323,7 +2327,9 @@ While composition offers model extensibility, it does not imply a hierarchy betw
To support polymorphism, OpenAPI Specification adds the support of the `discriminator` field.
When used, the `discriminator` will be the name of the property used to decide which schema definition is used to validate the structure of the model.
As such, the `discriminator` field MUST be a required field.
The value of the chosen property has to be the friendly name given to the model under the `definitions` property.
There are are two ways to define the value of a discriminator for an inheriting instance.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point -- we rely heavily on external schema files via $ref. For example, if Cat and Dog are defined externally, I should still be able to use them. However for a schema included from an external schema.json there is no name as there is for one defined in /components/definitions. If all three schema (Pet, Cat, Doc) were defined externally (so that they can be used in multiple OpenAPI documents) and there is no single /components/definitions in which they reside, how would this work?

@webron
Copy link
Member Author

webron commented Feb 22, 2017

Thanks @DavidBiesack - I'd still rather leave the wording regarding the JSON Schema intact, based on my experience with users in the past.

@darrelmiller
Copy link
Member

Latest updates LGTM 🎈


Further information about the properties can be found in [JSON Schema Core](http://json-schema.org/latest/json-schema-core.html) and [JSON Schema Validation](http://json-schema.org/latest/json-schema-validation.html).
Further information about the properties can be found in [JSON Schema Core](https://tools.ietf.org/html/draft-wright-json-schema-00) and [JSON Schema Validation](https://tools.ietf.org/html/draft-wright-json-schema-validation-00).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you call it "JSON Schema Core" but you reference it earlier as "JSON Schema Specification Wright Draft 00". Make a decision and use it in both places.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON Schema is split into two specifications - Core and Validation. Can't keep it as one, and shouldn't reference both every single time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough.

versions/3.0.md Outdated
- format - See [Data Type Formats](#dataTypeFormat) for further details. While relying on JSON Schema's defined formats, the OAS offers a few additional predefined formats.
- default - The default value represents what would be assumed by the consumer of the input as the value of the schema if one is not provided. Unlike JSON Schema, the value MUST conform to the defined type for the Schema Object defined at the same level. For example, of `type` is `string`, then `default` can be `"foo"`` but cannot be `1`.

Alternatively, any time a Scheme Object can be used, a [Reference Object](#referenceObject) can be used in place. This allows referencing definitions in place of defining them inline. Effectively, it is the `$ref` property in JSON Schema but follows the same guidelines and restrictions as the Reference Object. For example, additional properties alongside a `$ref` SHALL be ignored.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "in place" be "in its place"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The third sentence doesn't make sense to me. What about mentioning the caveat about mixing other properties with $ref into the Reference Object documentation and omitting the last two sentences?

@whitlockjc
Copy link
Member

:shipit:

@webron webron merged commit 026a1aa into OpenAPI.next Feb 22, 2017
@webron
Copy link
Member Author

webron commented Feb 22, 2017

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants