-
Notifications
You must be signed in to change notification settings - Fork 9.1k
OperationRef changes and more #1103
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
…dm/operationref # Conflicts: # versions/3.0.md
versions/3.0.md
Outdated
@@ -1739,8 +1739,8 @@ This object can be extended with [Specification Extensions](#specificationExtens | |||
|
|||
The key used to identify the [Path Item Object](#pathItemObject) is a variable expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. |
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.
"variable expression" should be "runtime expression"
versions/3.0.md
Outdated
@@ -1739,8 +1739,8 @@ This object can be extended with [Specification Extensions](#specificationExtens | |||
|
|||
The key used to identify the [Path Item Object](#pathItemObject) is a variable expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. | |||
A simple example might be `$request.body#/url`. | |||
However, using [variable substitution](#variableSubstitution) syntax the complete HTTP message can be accessed. | |||
This includes accessing any part of a body that can be accessed using a JSON Pointer [RFC6901](https://tools.ietf.org/html/rfc6901). |
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.
We should call out that this feature is only supported for JSON content. OpenAPI does not support XPath for XML bodies.
versions/3.0.md
Outdated
@@ -1739,8 +1739,8 @@ This object can be extended with [Specification Extensions](#specificationExtens | |||
|
|||
The key used to identify the [Path Item Object](#pathItemObject) is a variable expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. | |||
A simple example might be `$request.body#/url`. | |||
However, using [variable substitution](#variableSubstitution) syntax the complete HTTP message can be accessed. | |||
This includes accessing any part of a body that can be accessed using a JSON Pointer [RFC6901](https://tools.ietf.org/html/rfc6901). |
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.
We should probably add a note that such JSON Paths SHOULD refer to JSON scalar values. (Will this work for non-scalars like JSON arrays and JSON objects? That will result in spaces and special characters in the URL.)
versions/3.0.md
Outdated
@@ -1739,8 +1739,8 @@ This object can be extended with [Specification Extensions](#specificationExtens | |||
|
|||
The key used to identify the [Path Item Object](#pathItemObject) is a variable expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. | |||
A simple example might be `$request.body#/url`. | |||
However, using [variable substitution](#variableSubstitution) syntax the complete HTTP message can be accessed. | |||
This includes accessing any part of a body that can be accessed using a JSON Pointer [RFC6901](https://tools.ietf.org/html/rfc6901). |
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.
Suggest:
Implementations MUST preserve the text representation of the value.
(We don't want a JSON response with #/foo being a number 0.999999 and the implementation parsing the number as a float that gets changed to 1.0 or .9999997 for example.)
versions/3.0.md
Outdated
@@ -1739,8 +1739,8 @@ This object can be extended with [Specification Extensions](#specificationExtens | |||
|
|||
The key used to identify the [Path Item Object](#pathItemObject) is a variable expression that can be evaluated in the context of a runtime HTTP request/response to identify the URL to be used for the callback request. | |||
A simple example might be `$request.body#/url`. | |||
However, using [variable substitution](#variableSubstitution) syntax the complete HTTP message can be accessed. | |||
This includes accessing any part of a body that can be accessed using a JSON Pointer [RFC6901](https://tools.ietf.org/html/rfc6901). |
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.
Are the values URL encoded when constructing the URL?
What happens when string data from the body contains /
or ?
or &
characters - are they URL encoded? I imagine /
would be useful to not encode if it appears in a path element. If the JSON body contains
{ "args" : "?start=0&limit=1000" }
Can I use a URL such as "..../path/to/query{$response.body#/args}"
to yield
"..../path/to/query?start=0&limit=1000"
?
versions/3.0.md
Outdated
Where the `$request.path.id` is the value passed in the request to `/users/{id}`. | ||
|
||
##### Response Payload Example | ||
When a runtime expression evaluates to null, no parameter value is passed to the target operation. |
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.
"no parameter value is passed" is not well-defined and probably should be "the expression resolves to an empty string"
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.
But that means that the target operation would not use the default value from an optional parameter. That would not be the expected behavior.
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 see the need to allow falling back to the default and think this should be specified here (I assume you are referring to the default
value define in a JSON schema for an operation parameter - please confirm.)
However, there is a difference between the value at the JSON pointer being null (valid JSON) compared to the item the JSON path refers to not existing. If the JSON pointer value is null, I think that should be passed; it may be significant (see my other comment about null).
versions/3.0.md
Outdated
Where the `$request.path.id` is the value passed in the request to `/users/{id}`. | ||
|
||
##### Response Payload Example | ||
When a runtime expression evaluates to null, no parameter value is passed to the target operation. |
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 this merits discussion. null is a valid value in a JSON object, so for the response
{ "foo" : { "bar" : null, "zip" : "" } }
a expression $response.body#/foo/bar
should resolve to null
- that may be significant.
Note that the expression $response.body#/foo/zip
will result in an empty string.
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.
Yes, in both those cases the JSON pointer successfully resolved and therefore the value should be passed.
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.
So "When a runtime expression evaluates to null," should be "When a runtime expression references a value that does not exist,"
token = as per [RFC7230](https://tools.ietf.org/html/rfc7230#section-3.2.6) | ||
``` | ||
|
||
The `name` identifier is case-sensitive, whereas `token` is not. |
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.
What is the behavior when an expression/path resolves to something that is not found?
for the response
{ "foo" : { "bar" : null, "zip" : "" } }
a expression $response.body#/foo/xyz
results in an empty string?
What about headers that are not found?
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 suspect the behavior of an unresolved expression should be determined based on its usage. For links, I think that parameter values should not be provided and for callbacks the callback should be disabled. However, I feel we need more real world experience to be able to make this call.
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.
As we open the Call for Comments period on OAS 3.0.0, we should raise this. Implementers will need guidance, and I don't like a specification with open-ended, undefined behavior.
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.
Have you read the HTTP spec? ;-)
# returns array of '#/components/schemas/repository' | ||
operationRef: '#paths~12.0~1repositories~1/{username}' | ||
parameters: | ||
username: $response.body#/username | ||
``` | ||
|
||
or an absolute `operationRef`: |
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.
Link back to #linkOperationId
, or if you add a section for Operation Reference, link to that.
versions/3.0.md
Outdated
|
||
Many operations require parameters to be passed, and these MAY be dynamic depending on the response itself. For computing links, and providing instructions to execute them, [variable substitution](#variableSubstitution) is used for accessing values in a response and using them as values while invoking the linked operation. | ||
For computing links, and providing instructions to execute them, a [runtime expression](#runtimeExpression) is used for accessing values in a response and using them as parameters while invoking the linked operation. | ||
|
||
##### Fixed Fields | ||
|
||
Field Name | Type | Description | ||
---|:---:|--- | ||
<a name="linkOperationRef"></a>operationRef | `string` | a relative or absolute reference to an OAS operation. This field is mutually exclusive with the `operationId` field, and must point to the fragment of a valid OAS definition. |
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.
"the fragment of a valid OAS definition" should be more precise:
.. and MUST point to a Path Item Object in an OAS definition.
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 actually must point to an operation. And there are examples that need to be fixed.
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.
yes, sorry - wrong reference; s/b [Operation Object](#operationObject)
#TDC: @darrelmiller to review additional feedback from @DavidBiesack and @fehguy and @usarid to give this a thorough read. |
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.
Overall ok with the proposed changed, but added a few comments - some related to the PR, some may be more general.
@@ -1761,7 +1761,6 @@ Content-Length: 123 | |||
|
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 you close the quotes around successUrls
to make it a valid JSON?
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.
#TDC: Done :)
versions/3.0.md
Outdated
|
||
|
||
```yaml | ||
myWebhook: | ||
'$request.body#/url': | ||
'http://notificationServer.com?transactionId={$request.body#/id}&email={$request.body#/email}}': |
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.
There's an extra }
at the end.
versions/3.0.md
Outdated
|
||
##### Fixed Fields | ||
|
||
Field Name | Type | Description | ||
---|:---:|--- | ||
<a name="linkOperationRef"></a>operationRef | `string` | a relative or absolute reference to an OAS operation. This field is mutually exclusive with the `operationId` field, and must point to the fragment of a valid OAS definition. | ||
<a name="linkOperationId"></a>operationId | `string` | the name of an _existing_, resolvable OAS operation, as defined with a unique `operationId`. This field is mutually exclusive with the `operationRef` field. Relative `operationRef` values MAY be used to locate an existing [Operation Object](#operationObject) in the OAS. | ||
<a name="linkParameters"></a>parameters | Map[`string` \| Any \| [{expression}](#variableSubstitution)] | A map representing parameters to pass to the operation as specified with `operationId` or identified via `operationRef`. The key is the parameter name to be used, whereas the value can be a constant or an expression to be evaluated and passed to the linked operation. | ||
<a name="linkHeaders"></a>headers | Map[`string`, [Header Object](#headerObject) \| [Reference Object](#referenceObject)] | Maps a header name to its definition. Note that [RFC7230](https://tools.ietf.org/html/rfc7230#page-22) states header names are case insensitive. This represents the headers to pass to the linked resource. Where conflicts occur between these headers, and those defined in the related operation, these headers override. | ||
<a name="linkParameters"></a>parameters | Map[`string` \| Any \| [{expression}](#runtimeExpression)] | A map representing parameters to pass to an operation as specified with `operationId` or identified via `operationRef`. The key is the parameter name to be used, whereas the value can be a constant or an expression to be evaluated and passed to the linked operation. |
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.
- Map[
string
| Any | {expression}] -> Map[string
, Any | {expression}] - How do we know what type of parameters those are? Do we match the name to the parameter in the operation itself and try to match it? Names do not have to be unique among different parameter types, what happens in case of ambiguity? If there is name matching, and a name is not found, is the parameter ignored?
- Something you brought up in the past - how do we pass a request body?
As a way to solve the first two, we can reuse something from the runtime expressions - if there's a potential ambiguity, the parameter name can be prefixed by the type (path.
, header.
...). In that case, we can also use body
or requestBody
to denote a Request Body.
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.
Hadn't caught the ambiguous name issue and I'd forgot about the request body thing.
Response header | `$response.header.Server` | Single header values only are available | ||
|
||
Runtime expressions preserve the type of the referenced value. | ||
Expression values can be embeded into string values by surrounding the expression with `{}` curly braces. |
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.
Do we assume that in case of URLs they would be URL encoded and there's no need to escape curly braces if they are part of them as they're already encoded (including in query parameters)?
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.
No need to escape curly braces.
versions/3.0.md
Outdated
The runtime expression is defined by the following [ABNF](https://tools.ietf.org/html/rfc5234) syntax | ||
|
||
``` | ||
expression = ( "$url" | "$method" | "$request." [ source ] | "$response." [ source ]) |
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.
Please confirm - this ABNF states that source is optional with $request.
and $response.
which implies that naked $response.
is a valid expression - it's not clear if that is your intent or what that means. Should these omit the brackets:
expression = ( "$url" | "$method" | "$request." source | "$response." source )
versions/3.0.md
Outdated
links: | ||
UserRepositories: | ||
# returns array of '#/components/schemas/repository' | ||
operationRef: '#paths~12.0~1repositories~1/{username}' |
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 be #/paths
?
#TDC: Good with curly braces
|
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.
merge the darn PR
Notable changes:
I'd better stop making changes before this PR gets even bigger. /cc @OAI/tdc