-
Notifications
You must be signed in to change notification settings - Fork 9.1k
v3.??? Data vs Serialized Examples in Example Objects #4647
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
Conversation
@mikekistler fixed that example- it had been done with integers but those aren't interesting serialization cases! So I switched to strings. I also added some text about it being easier/less ambiguous to parse the serialized example and validate the data in many cases than to try to go the other way around. |
@mikekistler I have clarified the serialization rules in the latest added commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will help clarify what examples are and how they should be used.
My comments are intended to clarify some points and also to make this change a more evolutionary transition.
examples: | ||
oneMinute: | ||
dataValue: 60 | ||
serializedValue: 'X-Rate-Limit-Reset: 60' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love that you have added all these examples!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly it was one of the best things about writing the PR and is what convinced me it's worth making a strong case for it.
|
||
##### Fixed Fields | ||
|
||
| Field Name | Type | Description | | ||
| ---- | :----: | ---- | | ||
| <a name="example-summary"></a>summary | `string` | Short description for the example. | | ||
| <a name="example-description"></a>description | `string` | Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | | ||
| <a name="example-value"></a>value | Any | Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. | | ||
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The `value` field and `externalValue` field are mutually exclusive. See the rules for resolving [Relative References](#relative-references-in-api-description-uris). | | ||
| <a name="example-data-value"></a>dataValue | Any | An example of the data structure that MUST be valid according to the relevant [Schema Object](#schema-object). If this field is present, `externalDataValue`, `value`, and `externalValue` MUST be absent. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since JSON Schemas validate "instances", should we use "instance" instead of "data structure"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't decide which language was better. Easy to tweak at any point- I'll think about it as I do the other updates. [EDIT: I decided "instance" was too JSON Schema jargon-y, plus we go outside of the JSON Schema instance model with things like raw binary data.]
src/oas.md
Outdated
|
||
##### Example Object Examples | ||
Historically, the Example Object's `value` and `externalValue` field and the non-Schema Object singular `example` fields were intended to show examples of the serialized form, while allowing JSON or YAML examples to be included inline rather than as serialized strings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't speak to the "original intent" for these fields -- I wasn't involved at the time. But I wonder if this was really consciously decided as the intent, and then somehow omitted from the spec, or if instead it was not really understood that there is a difference between the data value and serialized value and that is why the distinction was not included in the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikekistler I understand that tooling vendors have implemented it differently, but these quotes from 3.0.3 seem pretty clear to me, and we've debated this before and always agreed that the encoded/serialized form was the intent. AFAIK, this effort by you right now is the first time anyone deeply involved has taken the opposite position in terms of what the wording means:
From the Parameter Object:
When
example
orexamples
are provided in conjunction with the schema object, the example MUST follow the prescribed serialization strategy for the parameter.
From the Media Type Object example
field:
The example object SHOULD be in the correct format as specified by the media type.
From the Media Type Object examples
field:
Examples of the media type. Each example object SHOULD match the media type and specified schema if present.
From the Example Object value
field:
To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary.
From the Example Object externalValue
field:
This provides the capability to reference examples that cannot easily be included in JSON or YAML documents.
From the Example Object after the fixed fields table:
In all cases, the example value is expected to be compatible with the type schema of its associated value. Tooling implementations MAY choose to validate compatibility automatically, and reject the example value(s) if incompatible.
I honestly don't see how all of this above, taken together, can be interpreted in any other way.
{ | ||
"author": "A. Writer", | ||
"title": "An Older Book", | ||
"rating": 4.5 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this serialized value be a string, which condensed white-space (as was done above)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikekistler it is a string, that's what the |
at the end of the serializedValue: |
does (YAML block literal).
As for minimizing, I did that for the parameter because it has to be shoved into the query string. This is presumed to be for a body, so it might be sent without that minimizing. But TBH I was just trying out all sorts of different things, I'm not super-attached to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on an update hopefully tonight, or at least before the meeting tomorrow morning.
{ | ||
"author": "A. Writer", | ||
"title": "An Older Book", | ||
"rating": 4.5 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikekistler it is a string, that's what the |
at the end of the serializedValue: |
does (YAML block literal).
As for minimizing, I did that for the parameter because it has to be shoved into the query string. This is presumed to be for a body, so it might be sent without that minimizing. But TBH I was just trying out all sorts of different things, I'm not super-attached to this.
|
||
##### Fixed Fields | ||
|
||
| Field Name | Type | Description | | ||
| ---- | :----: | ---- | | ||
| <a name="example-summary"></a>summary | `string` | Short description for the example. | | ||
| <a name="example-description"></a>description | `string` | Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | | ||
| <a name="example-value"></a>value | Any | Embedded literal example. The `value` field and `externalValue` field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. | | ||
| <a name="example-external-value"></a>externalValue | `string` | A URI that identifies the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The `value` field and `externalValue` field are mutually exclusive. See the rules for resolving [Relative References](#relative-references-in-api-description-uris). | | ||
| <a name="example-data-value"></a>dataValue | Any | An example of the data structure that MUST be valid according to the relevant [Schema Object](#schema-object). If this field is present, `externalDataValue`, `value`, and `externalValue` MUST be absent. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't decide which language was better. Easy to tweak at any point- I'll think about it as I do the other updates. [EDIT: I decided "instance" was too JSON Schema jargon-y, plus we go outside of the JSON Schema instance model with things like raw binary data.]
examples: | ||
oneMinute: | ||
dataValue: 60 | ||
serializedValue: 'X-Rate-Limit-Reset: 60' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly it was one of the best things about writing the PR and is what convinced me it's worth making a strong case for it.
src/oas.md
Outdated
|
||
##### Example Object Examples | ||
Historically, the Example Object's `value` and `externalValue` field and the non-Schema Object singular `example` fields were intended to show examples of the serialized form, while allowing JSON or YAML examples to be included inline rather than as serialized strings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mikekistler I understand that tooling vendors have implemented it differently, but these quotes from 3.0.3 seem pretty clear to me, and we've debated this before and always agreed that the encoded/serialized form was the intent. AFAIK, this effort by you right now is the first time anyone deeply involved has taken the opposite position in terms of what the wording means:
From the Parameter Object:
When
example
orexamples
are provided in conjunction with the schema object, the example MUST follow the prescribed serialization strategy for the parameter.
From the Media Type Object example
field:
The example object SHOULD be in the correct format as specified by the media type.
From the Media Type Object examples
field:
Examples of the media type. Each example object SHOULD match the media type and specified schema if present.
From the Example Object value
field:
To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary.
From the Example Object externalValue
field:
This provides the capability to reference examples that cannot easily be included in JSON or YAML documents.
From the Example Object after the fixed fields table:
In all cases, the example value is expected to be compatible with the type schema of its associated value. Tooling implementations MAY choose to validate compatibility automatically, and reject the example value(s) if incompatible.
I honestly don't see how all of this above, taken together, can be interpreted in any other way.
@mikekistler I have updated quite a few things, and left other things the same, with the upshot being that this PR is only about adding new fields to the Example Object and showing their use:
|
There's a lot of support for this change and especially for the examples that are added. We need to discuss naming before merging, but we think this can go into 3.2. |
Co-authored-by: Dan Hudlow <[email protected]>
@OAI/tsc and all, I have filed several issues to split out various related conversations and keep this PR moving to conclusion:
|
examples: | ||
number: | ||
dataValue: 12345678 | ||
serializedValue: "token: 12345678" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a second example, demonstrating the use of an array coming from deserializing the simple style?
examples: | |
number: | |
dataValue: 12345678 | |
serializedValue: "token: 12345678" | |
examples: | |
one number: | |
dataValue: 12345678 | |
serializedValue: "token: 12345678" | |
two numbers: | |
dataValue: | |
- 12345678 | |
- 99999999 | |
serializedValue: "token: 12345678,99999999" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karenetheridge as noted in the past TDC call, I'd like to handle newly added examples separately, otherwise we'll never finish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karenetheridge upon further thought, I'm going to split this PR up to separate the new fields from all of the extra example updates. I'll take this request into consideration then- I think that might be better than either allowing endless new example requests here or trying to keep them out of this process entirely.
# JSON Text Sequences require an unprintable character | ||
# that cannot be escaped in a YAML string, and therefore | ||
# must be placed in an external document shown below | ||
externalValue: examples/log.json-seq | ||
externalSerializedValue: examples/log.json-seq |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be really cool if we had the html renderer detect this keyword and add a hyperlink to a real file named "./examples/log.json-seq" in the github-pages repo.
Co-authored-by: Karen Etheridge <[email protected]>
|
||
##### Fixed Fields | ||
|
||
| Field Name | Type | Description | | ||
| ---- | :----: | ---- | | ||
| <a name="example-summary"></a>summary | `string` | Short description for the example. | | ||
| <a name="example-description"></a>description | `string` | Long description for the example. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | | ||
| <a name="example-data-value"></a>dataValue | Any | An example of the data structure that MUST be valid according to the relevant [Schema Object](#schema-object). If this field is present, `externalDataValue`, `value`, and `externalValue` MUST be absent. | | ||
| <a name="example-external-data-value"></a>externalDataValue | `string` | A URI that identifies the data example in a separate document, allowing for values not easily expressed in JSON or YAML. This is usually only needed when working with binary data. The value MUST be valid according to the relevant Schema Object. If this field is present, then `dataValue`, `value`, and `externalValue` MUST be absent. See also the rules for resolving [Relative URI References](#relative-references-in-api-description-uris). | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from some clarifications that could be postponed to another PR, my big concern is that I can't make heads or tails out of what a non-serialized external value looks like. In my mind, external values are inherently serialized: if you can provide externalDataValue: ./image.png
and the image is treated opaquely then it implies that when you provide externalDataValue: ./data.json
then the JSON document will be treated opaquely, and this would semantically match dataValue: "{ ... }"
not dataValue: { ... }
.
If you wanted the latter then the phrase "allowing for values not easily expressed in JSON or YAML" doesn't seem right, plus if all you want is to move a JSON data structure to an external URI, you can just use $ref
at the usage point for the example value? Yes, that means the whole Example Object is externalized but... that seems fine?
It is my belief that we should merely clarify that externalValue
is treated opaquely (i.e., as a serialized value) and skip adding externalDataValue
and externalSerializedValue
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
externalDataValue
acts just like the $ref
keyword -- the serialization level of the file is the same as the referencing document, but it's in a separate file solely because of its size (presumably), or to perhaps allow it to be modified at a different cadence than the referencing document itself (although that makes less sense here when the example needs to align with the schema).
I would imagine it would be the least-used of the four new keywords, but I see no reason to omit it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karenetheridge so you disagree with the text as written in this table and with the example on line 2328? If it works like this, why not just allow dataValue
to be a reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because then you can't have an example that uses a property named $ref
, this has been discussed extensively in past issues, search for an issue allowing for combining examples.
} | ||
``` | ||
|
||
###### Binary Examples |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might also be nice to show a data
-URL-scheme example. My assumption is that what URL schemes an interpreter of an OpenAPI description supports are completely out of scope, but there's no reason one couldn't support the data scheme?
Something like:
externalSerializedValue: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABGdBTUEAALGPC_xhBQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAAqADAAQAAAABAAAAAgAAAADO0J6QAAAAEElEQVQIHWP8zwACTGCSAQANHQEDqtPptQAAAABJRU5ErkJggg%3D%3D"`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hudlow can you please file an issue requesting that the OAS support this for external example fields (regardless of which external fields we end up having)? I think it is an interesting idea worth discussing but orthogonal to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: #4674
Co-authored-by: Dan Hudlow <[email protected]>
I am closing this in favor of the following PRs, because this is too big and the conversation has a lot of complex threads that have already been resolved.
|
This is most of what we would do for the first and most essential of three Example Object related proposals I went over in the last TDC call. I'm posting it because:
Please look through this and particularly focus on how this allowed me to change our in-spec examples to make many things more clear, and show how OAD authors can similarly make their intent clear.
Note that the changes to the XML examples don't (I think) assume the
nodeType
change in PR #4592, but I might have lost track of that if you see something strange there. The point is that this helps tremendously in showing expected XML behavior.