diff --git a/src/arazzo.md b/src/arazzo.md index fbfafe7..85dbec3 100644 --- a/src/arazzo.md +++ b/src/arazzo.md @@ -35,6 +35,8 @@ The Arazzo Specification can articulate these workflows in a human-readable and - [Components Object](#components-object) - [Reusable Object](#reusable-object) - [Criterion Object](#criterion-object) + - [Expression Type Object](#expression-type-object) + - [Selector Object](#selector-object) - [Request Body Object](#request-body-object) - [Payload Replacement Object](#payload-replacement-object) - [Runtime Expressions](#runtime-expressions) @@ -188,7 +190,7 @@ The metadata MAY be used by the clients if needed. ##### Fixed Fields | Field Name | Type | Description | -| ---|:---:|--- | +| --- | :---: | --- | | title | `string` | **REQUIRED**. A human readable title of the Arazzo Description. | | summary | `string` | A short summary of the Arazzo Description. | | description | `string` | A description of the purpose of the workflows defined. [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation. | @@ -248,7 +250,7 @@ Describes the steps to be taken across one or more APIs to achieve an objective. | steps | [[Step Object](#step-object)] | **REQUIRED**. An ordered list of steps where each step represents a call to an API operation or to another workflow. | | successActions | [[Success Action Object](#success-action-object) \| [Reusable Object](#reusable-object)] | A list of success actions that are applicable for all steps described under this workflow. These success actions can be overridden at the step level but cannot be removed there. If a Reusable Object is provided, it MUST link to success actions defined in the [components/successActions](#components-object) of the current Arazzo document. The list MUST NOT include duplicate success actions. | | failureActions | [[Failure Action Object](#failure-action-object) \| [Reusable Object](#reusable-object)] | A list of failure actions that are applicable for all steps described under this workflow. These failure actions can be overridden at the step level but cannot be removed there. If a Reusable Object is provided, it MUST link to failure actions defined in the [components/failureActions](#components-object) of the current Arazzo document. The list MUST NOT include duplicate failure actions. | -| outputs | Map[`string`, {expression}] | A map between a friendly name and a dynamic output value. The name MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. | +| outputs | Map[`string`, {expression} \| [Selector Object](#selector-object) ] | A map between a friendly name and a dynamic output value defined using a [Runtime Expression](#runtime-expressions) or [Selector Object](#selector-object). The name MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. | | parameters | [[Parameter Object](#parameter-object) \| [Reusable Object](#reusable-object)] | A list of parameters that are applicable for all steps described under this workflow. These parameters can be overridden at the step level but cannot be removed there. Each parameter MUST be passed to an operation or workflow as referenced by `operationId`, `operationPath`, or `workflowId` as specified within each step. If a Reusable Object is provided, it MUST link to a parameter defined in the [components/parameters](#components-object) of the current Arazzo document. The list MUST NOT include duplicate parameters. | @@ -308,7 +310,7 @@ Describes a single workflow step which MAY be a call to an API operation ([OpenA | successCriteria | [[Criterion Object](#criterion-object)] | A list of assertions to determine the success of the step. Each assertion is described using a [Criterion Object](#criterion-object). All assertions `MUST` be satisfied for the step to be deemed successful. | | onSuccess | [[Success Action Object](#success-action-object) \| [Reusable Object](#reusable-object)] | An array of success action objects that specify what to do upon step success. If omitted, the next sequential step shall be executed as the default behavior. If multiple success actions have similar `criteria`, the first sequential action matching the criteria SHALL be the action executed. If a success action is already defined at the [Workflow](#workflow-object), the new definition will override it but can never remove it. If a Reusable Object is provided, it MUST link to a success action defined in the [components](#components-object) of the current Arazzo document. The list MUST NOT include duplicate success actions. | | onFailure | [[Failure Action Object](#failure-action-object) \| [Reusable Object](#reusable-object)] | An array of failure action objects that specify what to do upon step failure. If omitted, the default behavior is to break and return. If multiple failure actions have similar `criteria`, the first sequential action matching the criteria SHALL be the action executed. If a failure action is already defined at the [Workflow](#workflow-object), the new definition will override it but can never remove it. If a Reusable Object is provided, it MUST link to a failure action defined in the [components](#components-object) of the current Arazzo document. The list MUST NOT include duplicate failure actions. | -| outputs | Map[`string`, {expression}] | A map between a friendly name and a dynamic output value defined using a [Runtime Expression](#runtime-expressions). The name MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. | +| outputs | Map[`string`, {expression} \| [Selector Object](#selector-object)] | A map between a friendly name and a dynamic output value defined using a [Runtime Expression](#runtime-expressions) or [Selector Object](#selector-object). The name MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -392,7 +394,7 @@ Describes a single step parameter. A unique parameter is defined by the combinat | --- | :---: | --- | | name | `string` | **REQUIRED**. The name of the parameter. Parameter names are _case sensitive_. | | in | `string` | The location of the parameter. Possible values are `"path"`, `"query"`, `"header"`, or `"cookie"`. When the step in context specifies a `workflowId`, then all parameters map to workflow inputs. In all other scenarios (e.g., a step specifies an `operationId`), the `in` field MUST be specified. | -| value | Any \| {expression} | **REQUIRED**. The value to pass in the parameter. The value can be a constant or a [Runtime Expression](#runtime-expressions) to be evaluated and passed to the referenced operation or workflow. | +| value | Any \| {expression} \| [Selector Object](#selector-object) | **REQUIRED**. The value to pass in the parameter. The value can be a constant, a [Runtime Expression](#runtime-expressions), or a [Selector Object](#selector-object) to be evaluated and passed to the referenced operation or workflow. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -410,6 +412,15 @@ This object MAY be extended with [Specification Extensions](#specification-exten value: $inputs.x-api-key ``` +```yaml +- name: customerId + in: query + value: + expression: $inputs.customer + selector: $.details[0].id + type: jsonpath +``` + #### Success Action Object A single success action which describes an action to take upon success of a workflow step. There are two possible values for the `type` field: @@ -420,7 +431,7 @@ A single success action which describes an action to take upon success of a work ##### Fixed Fields | Field Name | Type | Description | -| --- | :---: | --- | +| --- | :---: | --- | | name | `string` | **REQUIRED**. The name of the success action. Names are _case sensitive_. | | type | `string` | **REQUIRED**. The type of action to take. Possible values are `"end"` or `"goto"`. | | workflowId | `string` | The [workflowId](#fixed-fields-2) referencing an existing workflow within the Arazzo Description to transfer to upon success of the step. This field is only relevant when the `type` field value is `"goto"`. If the referenced workflow is contained within an `arazzo` type `sourceDescription`, then the `workflowId` MUST be specified using a [Runtime Expression](#runtime-expressions) (e.g., `$sourceDescriptions..`) to avoid ambiguity or potential clashes. This field is mutually exclusive to `stepId`. | @@ -635,26 +646,26 @@ As part of a condition expression, you can use `boolean`, `null`, `number`, or ` | Type | Literal value | | --- | --- | | `boolean` | `true` or `false` | -| `null` | `null` | +| `null` | `null` | | `number` | Any number format supported in [Data Types](#data-types). | | `string` | Strings MUST use single quotes (') around the string. To use a literal single quote, escape the literal single quote using an additional single quote (''). | ##### Operators -| Operator | Description | +| Operator | Description | | --- | --- | -| `<`| Less than | -| `<=`| Less than or equal | -| `>`| Greater than | -| `>=`| Greater than or equal | -| `==`| Equal | -| `!=`| Not equal | -| `!`| Not | -| `&&`| And | -| \|\|| Or | -| `()`| Logical Grouping | -| `[]`| Index (0-based) | -| `.`| Property de-reference | +| `<` | Less than | +| `<=` | Less than or equal | +| `>` | Greater than | +| `>=` | Greater than or equal | +| `==` | Equal | +| `!=` | Not equal | +| `!` | Not | +| `&&` | And | +| \|\| | Or | +| `()` | Logical Grouping | +| `[]` | Index (0-based) | +| `.` | Property de-reference | String comparisons `MUST` be case insensitive. @@ -664,8 +675,7 @@ String comparisons `MUST` be case insensitive. | --- | :---: | --- | | context | `{expression}` | A [Runtime Expression](#runtime-expressions) used to set the context for the condition to be applied on. If `type` is specified, then the `context` MUST be provided (e.g. `$response.body` would set the context that a JSONPath query expression could be applied to). | | condition | `string` | **REQUIRED**. The condition to apply. Conditions can be simple (e.g. `$statusCode == 200` which applies an operator on a value obtained from a runtime expression), or a regex, or a JSONPath expression. For regex or JSONPath, the `type` and `context` MUST be specified. | -| type | `string` \| [Criterion Expression Type Object](#criterion-expression-type-object) | The type of condition to be applied. If specified, the options allowed are `simple`, `regex`, `jsonpath` or `xpath`. If omitted, then the condition is assumed to be `simple`, which at most combines literals, operators and [Runtime Expressions](#runtime-expressions). If `jsonpath`, then the expression MUST conform to [JSONPath](https://tools.ietf.org/html/rfc9535). If `xpath` the expression MUST conform to [XML Path Language 3.1](https://www.w3.org/TR/xpath-31/#d2e24229). Should other variants of JSONPath or XPath be required, then a [Criterion Expression Type Object](#criterion-expression-type-object) MUST be specified. | - +| type | `string` \| [Expression Type Object](#expression-type-object) | The type of condition to be applied. If specified, the options allowed are `simple`, `regex`, `jsonpath` or `xpath`. If omitted, then the condition is assumed to be `simple`, which at most combines literals, operators and [Runtime Expressions](#runtime-expressions). If `jsonpath`, then the expression MUST conform to [JSONPath](https://tools.ietf.org/html/rfc9535). If `xpath` the expression MUST conform to [XML Path Language 3.1](https://www.w3.org/TR/xpath-31/#d2e24229). Should other variants of JSONPath or XPath be required, then a [Expression Type Object](#expression-type-object) MUST be specified. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -693,12 +703,9 @@ A JSONPath Condition example: type: jsonpath ``` -#### Criterion Expression Type Object - -An object used to describe the type and version of an expression used within a [Criterion Object](#criterion-object). If this object is not defined, then the following defaults apply: +#### Expression Type Object -- JSONPath as described by [RFC9535](https://tools.ietf.org/html/rfc9535) -- XPath as described by [XML Path Language 3.1](https://www.w3.org/TR/xpath-31) +An object used to describe the type and version of an expression used within a [Criterion Object](#criterion-object) or [Selector Object](#selector-object). Defining this object gives the ability to utilize tooling compatible with older versions of either JSONPath or XPath. @@ -706,12 +713,22 @@ Defining this object gives the ability to utilize tooling compatible with older | Field Name | Type | Description | | --- | :---: | --- | -| type | `string` | **REQUIRED**. The type of condition to be applied. The options allowed are `jsonpath` or `xpath`. | -| version | `string` | **REQUIRED**. A short hand string representing the version of the expression type being used. The allowed values for JSONPath are `draft-goessner-dispatch-jsonpath-00`. The allowed values for XPath are `xpath-30`, `xpath-20`, or `xpath-10`. | +| type | `string` | **REQUIRED**. The selector type. The options allowed are `jsonpath`, `xpath`, or `jsonpointer`. | +| version | `string` | **REQUIRED**. A short hand string representing the version of the expression type being used. The allowed values for JSONPath are `rfc9535` or `draft-goessner-dispatch-jsonpath-00`. The allowed values for XPath are `xpath-30`, `xpath-20`, or `xpath-10`. The allowed value for JSON Pointer is `rfc6901`. | + +The supported expression selector types and versions are as follows: + +| Type | Allowed Versions | Default | +| ---- | --- | --- | +| `jsonpath` | `rfc9535`, `draft-goessner-dispatch-jsonpath-00` | `rfc9535` | +| `xpath` | `xpath-31`, `xpath-30`, `xpath-20`, `xpath-10` | `xpath-31` | +| `jsonpointer` | `rfc6901` (added for completeness) | `rfc6901` | + +If this object is not defined, the default version for the selector type MUST be used. This object MAY be extended with [Specification Extensions](#specification-extensions). -##### Criterion Expression Type Examples +##### Expression Type Examples A JSONPath example: @@ -727,6 +744,45 @@ An XPath example: version: xpath-30 ``` +#### Selector Object + +An object which enables fine-grained traversal and precise data selection from structured data such as JSON or XML, using a defined selector syntax such as JSONPath or XPath. + +##### Fixed Fields + +| Field Name | Type | Description | +| --- | :---: | --- | +| expression | {expression} | **REQUIRED**. A valid [Runtime Expressions](#runtime-expressions) which MUST evaluate to structured data (e.g., `$response.body`). | +| selector | `string` | **REQUIRED**.A selector expression (e.g., $.items[0].id, /Envelope/Item) in the form of JSONPath expression, XPath expression, or JSON Pointer expression. | +| type | `string` \| [Expression Type Object](#expression-type-object) | **REQUIRED**. The selector expression type to use (e.g., `jsonpath`, `xpath`, or `jsonpointer`). If `jsonpath`, then the expression MUST conform to [JSONPath](https://tools.ietf.org/html/rfc9535). If `xpath` the expression MUST conform to [XML Path Language 3.1](https://www.w3.org/TR/xpath-31/#d2e24229). Should other variants of JSONPath or XPath be required, then a [Expression Type Object](#expression-type-object) MUST be specified. | + + +##### Selector Object Examples + +An output example: + +```yaml + outputs: + userEmail: + expression: $response.body + selector: $.user.profile.email + type: jsonpath +``` + +A Step RequestBody example: + +```yaml + requestBody: + contentType: application/json + payload: + invoiceId: + expression: $steps.fetchXml.outputs.invoiceXml + selector: /Invoice/Header/InvoiceNumber + type: + type: xpath + version: xpath-30 +``` + #### Request Body Object A single request body describing the `Content-Type` and request body content to be passed by a step to an operation. @@ -736,7 +792,7 @@ A single request body describing the `Content-Type` and request body content to | Field Name | Type | Description | | --- | :---: | --- | | contentType | `string` | The Content-Type for the request content. If omitted then refer to Content-Type specified at the targeted operation to understand serialization requirements. | -| payload | Any | A value representing the request body payload. The value can be a literal value or can contain [Runtime Expressions](#runtime-expressions) which MUST be evaluated prior to calling the referenced operation. To represent examples of media types that cannot be naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. | +| payload | Any | A value representing the request body payload. The value can be a literal value or can contain [Runtime Expressions](#runtime-expressions) or [Selector Objects](#selector-object) which MUST be evaluated prior to calling the referenced operation. To represent examples of media types that cannot be naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. | | replacements | [[Payload Replacement Object](#payload-replacement-object)] | A list of locations and values to set within a payload. | This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -821,8 +877,14 @@ Describes a location within a payload (e.g., a request body) and a value to set | Field Name | Type | Description | | --- | :---: | --- | -| target | `string` | **REQUIRED**. A [JSON Pointer](https://tools.ietf.org/html/rfc6901) or [XPath Expression](https://www.w3.org/TR/xpath-31/#id-expressions) which MUST be resolved against the request body. Used to identify the location to inject the `value`. | -| value | Any \| {expression} | **REQUIRED**. The value set within the target location. The value can be a constant or a [Runtime Expression](#runtime-expressions) to be evaluated and passed to the referenced operation or workflow. | +| target | `string` | **REQUIRED**. A [JSON Pointer](https://tools.ietf.org/html/rfc6901), or [XPath Expression](https://www.w3.org/TR/xpath-31/#id-expressions), or [JSONPath](https://tools.ietf.org/html/rfc9535) which MUST be resolved against the request body. Used to identify the location to inject the `value`. | +| targetSelectorType | `string` \| [Expression Type Object](#expression-type-object) | The selector expression type to use (e.g., `jsonpath`, `xpath`, or `jsonpointer`). If `jsonpath`, then the `target` expression MUST conform to [JSONPath](https://tools.ietf.org/html/rfc9535). If `xpath` the expression MUST conform to [XML Path Language 3.1](https://www.w3.org/TR/xpath-31/#d2e24229). Should other variants of JSONPath or XPath be required, then a [Expression Type Object](#expression-type-object) MUST be specified. | +| value | Any \| {expression} \| [Selector Object](#selector-object) | **REQUIRED**. The value set within the target location. The value can be a constant, a [Runtime Expression](#runtime-expressions), or [Selector Objects](#selector-object) to be evaluated and passed to the referenced operation or workflow. | + +If `targetSelectorType` is omitted, then: + +- `target` MUST be interpreted as [JSON Pointer](https://tools.ietf.org/html/rfc6901)if the payload is `application/json`. +- `target` MUST be interpreted as [XPath Expression](https://www.w3.org/TR/xpath-31/#id-expressions) if the payload is `application/xml` or another XML-based media type. This object MAY be extended with [Specification Extensions](#specification-extensions). @@ -842,6 +904,31 @@ A literal example: value: 10 ``` +A JSONPath example using an Expression Type Object: + +```yaml + target: $.items[?(@.sku=='ABC123')].quantity + targetSelectorType: jsonpath + value: + expression: $steps.getInventory.outputs.payload + selector: $.newQuantity + type: jsonpath +``` + +An XPath example using older XPATH 3.0: + +```yaml + target: /Envelope/Header/CustomerId + targetSelectorType: + type: xpath + version: xpath-30 + value: + expression: $steps.fetchCustomerData.outputs.xml + selector: /CustomerInfo/Id + type: + type: xpath + version: xpath-30 +``` ### Runtime Expressions @@ -871,18 +958,18 @@ The runtime expression is defined by the following [ABNF](https://tools.ietf.org #### Examples -| Source Location | example expression | notes | +| Source Location | example expression | notes | | --- | :--- | :--- | -| HTTP Method | `$method` | The allowable values for the `$method` will be those for the HTTP operation. | +| HTTP Method | `$method` | The allowable values for the `$method` will be those for the HTTP operation. | | Requested media type | `$request.header.accept` | | -| Request parameter | `$request.path.id` | Request parameters MUST be declared in the `parameters` section of the parent operation or they cannot be evaluated. This includes request headers. | -| Request body property | `$request.body#/user/uuid` | In operations which accept payloads, references may be made to portions of the `requestBody` or the entire body. | -| Request URL | `$url` | | -| Response value | `$response.body#/status` | In operations which return payloads, references may be made to portions of the response body or the entire body. | -| Response header | `$response.header.Server` | Single header values only are available. | -| workflow input | `$inputs.username` or `$workflows.foo.inputs.username` | Single input values only are available. | -| Step output value | `$steps.someStepId.outputs.pets` | In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$steps.someStepId.outputs.pets#/0/id`) or the entire body. | -| Workflow output value | `$outputs.bar` or `$workflows.foo.outputs.bar` | In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$workflows.foo.outputs.mappedResponse#/name`) or the entire body. | +| Request parameter | `$request.path.id` | Request parameters MUST be declared in the `parameters` section of the parent operation or they cannot be evaluated. This includes request headers. | +| Request body property | `$request.body#/user/uuid` | In operations which accept payloads, references may be made to portions of the `requestBody` or the entire body. | +| Request URL | `$url` | | +| Response value | `$response.body#/status` | In operations which return payloads, references may be made to portions of the response body or the entire body. | +| Response header | `$response.header.Server` | Single header values only are available. | +| workflow input | `$inputs.username` or `$workflows.foo.inputs.username` | Single input values only are available. | +| Step output value | `$steps.someStepId.outputs.pets` | In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$steps.someStepId.outputs.pets#/0/id`) or the entire body. | +| Workflow output value | `$outputs.bar` or `$workflows.foo.outputs.bar` | In situations where the output named property return payloads, references may be made to portions of the response body (e.g., `$workflows.foo.outputs.mappedResponse#/name`) or the entire body. | | Components parameter | `$components.parameters.foo` | Accesses a foo parameter defined within the Components Object. | Runtime expressions preserve the type of the referenced value. @@ -971,7 +1058,7 @@ The proposed MIME media type for Arazzo documents (e.g. workflows) that require ## Appendix A: Revision History -| Version | Date | Notes | -| --- | --- | --- | -| 1.0.1 | 2025-01-16 | Patch release of the Arazzo Specification 1.0.1 | -| 1.0.0 | 2024-05-29 | First release of the Arazzo Specification | +| Version | Date | Notes | +| --- | --- | --- | +| 1.0.1 | 2025-01-16 | Patch release of the Arazzo Specification 1.0.1 | +| 1.0.0 | 2024-05-29 | First release of the Arazzo Specification | diff --git a/src/schemas/validation/README.md b/src/schemas/validation/README.md index a39f8c2..24c3a5e 100644 --- a/src/schemas/validation/README.md +++ b/src/schemas/validation/README.md @@ -1,18 +1,22 @@ -# OpenAPI Arazzo 1.0.x JSON Schema +# OpenAPI Arazzo 1.X.Y JSON Schema -Here you can find the JSON Schema for validating Arazzo Documents conforming to versions 1.0.x. +Here you can find the JSON Schema for validating Arazzo Documents conforming to versions 1.X.Y, which are published on [https://spec.openapis.org](https://spec.openapis.org). -As a reminder, the JSON Schema is not the source of truth for the Specification. -In cases of conflicts between the Specification itself and the JSON Schema, the -Specification wins. Also, some Specification constraints cannot be represented -with the JSON Schema so it's highly recommended to employ other methods to -ensure compliance. +Due to limitations of GitHub pages, the schemas on the spec site are served with `Content-Type: application/octet-stream`, but should be interpreted as `application/schema+json`. + +The sources in this directory, which have `WORK-IN-PROGRESS` in their `$id`s, are _not intended for direct use_. The iteration version of the JSON Schema can be found in the `$id` field. For example, the value of `$id: https://spec.openapis.org/arazzo/1.0/schema/2024-10-17` means this iteration was created on October 17, 2024. ## Contributing +As a reminder, the JSON Schema is not the source of truth for the Specification. +In cases of conflicts between the Specification itself and the JSON Schema, the +Specification wins. Also, some Specification constraints cannot be represented +with the JSON Schema so it's highly recommended to employ other methods to +ensure compliance. + To submit improvements to the schema, modify the `schema.yaml` and add test cases for your changes. The TSC will then: @@ -22,7 +26,7 @@ The TSC will then: ## Tests -The [test suite](../../tests/v1.0) is part of this package. +The [test suite](../../tests/schema) is part of this package. ```bash npm install diff --git a/src/schemas/validation/schema.yaml b/src/schemas/validation/schema.yaml index c48b83d..155466f 100644 --- a/src/schemas/validation/schema.yaml +++ b/src/schemas/validation/schema.yaml @@ -1,13 +1,13 @@ -$id: 'https://spec.openapis.org/arazzo/1.0/schema/WORK-IN-PROGRESS' +$id: 'https://spec.openapis.org/arazzo/1.1/schema/WORK-IN-PROGRESS' $schema: 'https://json-schema.org/draft/2020-12/schema' description: |- - The description of Arazzo v1.0.x documents + The description of Arazzo v1.1.x documents type: object properties: arazzo: description: The version number of the Arazzo Specification type: string - pattern: '^1\.0\.\d+(-.+)?$' + pattern: '^1\.1\.\d+(-.+)?$' info: $ref: '#/$defs/info' sourceDescriptions: @@ -35,7 +35,7 @@ $ref: '#/$defs/specification-extensions' unevaluatedProperties: false $defs: info: - $comment: https://spec.openapis.org/arazzo/v1.0#info-object + $comment: https://spec.openapis.org/arazzo/v1.1#info-object description: Provides metadata about the Arazzo description type: object properties: @@ -57,7 +57,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false source-description-object: - $comment: https://spec.openapis.org/arazzo/v1.0#source-description-object + $comment: https://spec.openapis.org/arazzo/v1.1#source-description-object description: |- Describes a source description (such as an OpenAPI description) that will be referenced by one or more workflows described within @@ -83,7 +83,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false workflow-object: - $comment: https://spec.openapis.org/arazzo/v1.0#workflow-object + $comment: https://spec.openapis.org/arazzo/v1.1#workflow-object description: Describes the steps to be taken across one or more APIs to achieve an objective type: object properties: @@ -130,11 +130,15 @@ $defs: - $ref: '#/$defs/failure-action-object' - $ref: '#/$defs/reusable-object' outputs: - description: A map between a friendly name and a dynamic output value + description: > + A map between a friendly name and a dynamic output value defined using a + Runtime Expression or Selector Object. Keys must match the regex: ^[a-zA-Z0-9\.\-_]+$ type: object patternProperties: '^[a-zA-Z0-9\.\-_]+$': - type: string + oneOf: + - type: string + - $ref: '#/$defs/selector-object' parameters: description: A list of parameters that are applicable for all steps described under this workflow type: array @@ -149,7 +153,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false step-object: - $comment: https://spec.openapis.org/arazzo/v1.0#step-object' + $comment: https://spec.openapis.org/arazzo/v1.1#step-object' description: |- Describes a single workflow step which MAY be a call to an API operation (OpenAPI Operation Object or another Workflow Object) @@ -202,11 +206,15 @@ $defs: - $ref: '#/$defs/failure-action-object' - $ref: '#/$defs/reusable-object' outputs: - description: A map between a friendly name and a dynamic output value defined using a runtime expression + description: > + A map between a friendly name and a dynamic output value defined using a + Runtime Expression or Selector Object. Keys must match the regex: ^[a-zA-Z0-9\.\-_]+$ type: object patternProperties: '^[a-zA-Z0-9\.\-_]+$': - type: string + oneOf: + - type: string + - $ref: '#/$defs/selector-object' required: - stepId oneOf: @@ -245,7 +253,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false request-body-object: - $comment: https://spec.openapis.org/arazzo/v1.0#request-body-object + $comment: https://spec.openapis.org/arazzo/v1.1#request-body-object description: The request body to pass to an operation as referenced by operationId or operationPath type: object properties: @@ -262,7 +270,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false criterion-object: - $comment: https://spec.openapis.org/arazzo/v1.0#criterion-object + $comment: https://spec.openapis.org/arazzo/v1.1#criterion-object description: |- An object used to specify the context, conditions, and condition types that can be used to prove or satisfy assertions specified in Step Object successCriteria, @@ -275,18 +283,17 @@ $defs: condition: description: The condition to apply type: string - anyOf: - - type: object - properties: - type: - description: The type of condition to be applied - enum: + type: + description: The type of condition to be applied or a reference to an expression type object + oneOf: + - type: string + enum: - simple - regex - jsonpath - xpath default: simple - - $ref: '#/$defs/criterion-expression-type-object' + - $ref: '#/$defs/expression-type-object' required: - condition dependentRequired: @@ -294,18 +301,21 @@ $defs: - context $ref: '#/$defs/specification-extensions' unevaluatedProperties: false - criterion-expression-type-object: - $comment: https://spec.openapis.org/arazzo/v1.0#criterion-expression-type-object - description: An object used to describe the type and version of an expression used within a Criterion Object + expression-type-object: + $comment: https://spec.openapis.org/arazzo/v1.1#expression-type-object + description: An object used to describe the type and version of an expression used within a Criterion Object or Selector Object. If the `version` is omitted, a default value is assumed based on the expression `type` type: object properties: type: - description: The type of condition to be applied + description: The type of selector to use enum: - jsonpath - xpath + - jsonpointer version: - description: A short hand string representing the version of the expression type + description: > + A short hand string representing the version of the expression type. + If omitted, the default for the selected type will be used. type: string required: - type @@ -320,7 +330,10 @@ $defs: then: properties: version: - const: draft-goessner-dispatch-jsonpath-00 + enum: + - rfc9535 + - draft-goessner-dispatch-jsonpath-00 + - if: required: - type @@ -334,9 +347,19 @@ $defs: - xpath-10 - xpath-20 - xpath-30 + - xpath-31 + + - if: + properties: + type: + const: jsonpointer + then: + properties: + version: + const: rfc6901 $ref: '#/$defs/specification-extensions' success-action-object: - $comment: https://spec.openapis.org/arazzo/v1.0#success-action-object + $comment: https://spec.openapis.org/arazzo/v1.1#success-action-object description: A single success action which describes an action to take upon success of a workflow step type: object properties: @@ -378,7 +401,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false failure-action-object: - $comment: https://spec.openapis.org/arazzo/v1.0#failure-action-object + $comment: https://spec.openapis.org/arazzo/v1.1#failure-action-object description: A single failure action which describes an action to take upon failure of a workflow step type: object properties: @@ -437,7 +460,7 @@ $defs: $ref: '#/$defs/specification-extensions' unevaluatedProperties: false reusable-object: - $comment: https://spec.openapis.org/arazzo/v1.0#reusable-object + $comment: https://spec.openapis.org/arazzo/v1.1#reusable-object description: A simple object to allow referencing of objects contained within the Components Object type: object properties: @@ -457,7 +480,7 @@ $defs: - reference unevaluatedProperties: false parameter-object: - $comment: https://spec.openapis.org/arazzo/v1.0#parameter-object + $comment: https://spec.openapis.org/arazzo/v1.1#parameter-object description: Describes a single step parameter type: object properties: @@ -473,36 +496,79 @@ $defs: - cookie value: description: The value to pass in the parameter - type: - - string - - boolean - - object - - array - - number - - 'null' + oneOf: + - type: + - string + - boolean + - array + - number + - 'null' + - $ref: '#/$defs/selector-object' required: - name - value $ref: '#/$defs/specification-extensions' unevaluatedProperties: false payload-replacement-object: - $comment: https://spec.openapis.org/arazzo/v1.0#payload-replacement-object + $comment: https://spec.openapis.org/arazzo/v1.1#payload-replacement-object description: Describes a location within a payload (e.g., a request body) and a value to set within the location type: object properties: target: - description: A JSON Pointer or XPath Expression which MUST be resolved against the request body + description: A JSONPath, JSON Pointer, or XPath Expression which MUST be resolved against the request body type: string + targetSelectorType: + description: > + The selector expression type to use (e.g., `jsonpath`, `xpath`, or `jsonpointer`). + Should an alternate version be required, the Expression Type Object may be used instead. + If omitted, defaults to JSON Pointer for `application/json` or XPath for XML-based media types. + oneOf: + - type: string + enum: + - jsonpointer + - jsonpath + - xpath + - $ref: "#/$defs/expression-type-object" value: - description: The value set within the target location - type: string + description: > + The value to set at the location defined by the target. May be a literal, + a runtime expression string, or a selector object. + oneOf: + - type: string + - $ref: '#/$defs/selector-object' required: - target - value unevaluatedProperties: false $ref: '#/$defs/specification-extensions' + selector-object: + $comment: https://spec.openapis.org/arazzo/v1.1#selector-object + description: An object which enables fine-grained traversal and precise data selection from structured data + type: object + properties: + expression: + description: A valid Runtime Expressions which MUST evaluate to structured data (e.g., `$response.body`) + type: string + selector: + description: A selector expression (e.g., $.items[0].id, /Envelope/Item) in the form of JSONPath expression, XPath expression, or JSON Pointer expression + type: string + type: + description: The selector expression type to use (e.g., `jsonpath`, `xpath`, or `jsonpointer`) or an Expression Type Object for older version support + oneOf: + - type: string + enum: + - jsonpointer + - jsonpath + - xpath + - $ref: '#/$defs/expression-type-object' + required: + - expression + - selector + - type + unevaluatedProperties: false + $ref: '#/$defs/specification-extensions' components-object: - $comment: https://spec.openapis.org/arazzo/v1.0#components-object + $comment: https://spec.openapis.org/arazzo/v1.1#components-object description: Holds a set of reusable objects for different aspects of the Arazzo Specification type: object properties: @@ -534,10 +600,10 @@ $defs: unevaluatedProperties: false $ref: '#/$defs/specification-extensions' specification-extensions: - $comment: https://spec.openapis.org/arazzo/v1.0#specification-extensions + $comment: https://spec.openapis.org/arazzo/v1.1#specification-extensions description: While the Arazzo Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points patternProperties: '^x-': true schema: - $comment: https://spec.openapis.org/arazzo/v1.0#schema-object + $comment: https://spec.openapis.org/arazzo/v1.1#schema-object $ref: 'https://json-schema.org/draft/2020-12/schema' diff --git a/tests/schema/fail/invalid-expression-type-object.arazzo.yaml b/tests/schema/fail/invalid-expression-type-object.arazzo.yaml new file mode 100644 index 0000000..8b9064c --- /dev/null +++ b/tests/schema/fail/invalid-expression-type-object.arazzo.yaml @@ -0,0 +1,20 @@ +arazzo: 1.1.0 +info: + title: Bad Expression Type Version + version: 1.1.0 +sourceDescriptions: + - name: example + url: 'https://example.com/openapi.yaml' + type: openapi +workflows: + - workflowId: wf2 + steps: + - stepId: step2 + operationId: getThings + outputs: + brokenSelector: + expression: $response.body + selector: '$.items[0]' + type: + type: xpath + version: rfc9535 diff --git a/tests/schema/fail/invalid-selector-object.arazzo.yaml b/tests/schema/fail/invalid-selector-object.arazzo.yaml new file mode 100644 index 0000000..4887273 --- /dev/null +++ b/tests/schema/fail/invalid-selector-object.arazzo.yaml @@ -0,0 +1,17 @@ +arazzo: 1.1.0 +info: + title: Invalid Selector Object (Missing Type) + version: 1.1.0 +sourceDescriptions: + - name: example + url: 'https://example.com/openapi.yaml' + type: openapi +workflows: + - workflowId: wf1 + steps: + - stepId: step1 + operationId: getStuff + outputs: + brokenOutput: + expression: $response.body + selector: $.data.id diff --git a/tests/schema/fail/invalid-targetSelectorType.arazzo.yaml b/tests/schema/fail/invalid-targetSelectorType.arazzo.yaml new file mode 100644 index 0000000..d6eeb37 --- /dev/null +++ b/tests/schema/fail/invalid-targetSelectorType.arazzo.yaml @@ -0,0 +1,19 @@ +arazzo: 1.1.0 +info: + title: Bad targetSelectorType + version: 1.1.0 +sourceDescriptions: + - name: example + url: 'https://example.com/openapi.yaml' + type: openapi +workflows: + - workflowId: wf3 + steps: + - stepId: step3 + operationId: updateItem + requestBody: + contentType: application/json + replacements: + - target: $.status + targetSelectorType: jmespath + value: completed diff --git a/tests/schema/pass/bnpl-example.yaml b/tests/schema/pass/bnpl-example.yaml index 514ded8..b311615 100644 --- a/tests/schema/pass/bnpl-example.yaml +++ b/tests/schema/pass/bnpl-example.yaml @@ -1,8 +1,8 @@ -arazzo: 1.0.0 +arazzo: 1.1.0 info: title: BNPL Workflow description summary: A buy now, pay later workflow example - version: 1.0.0 + version: 1.1.0 sourceDescriptions: - name: BnplApi url: https://raw.githubusercontent.com/OAI/Arazzo-Specification/main/examples/1.0.0/bnpl-openapi.yaml diff --git a/tests/schema/pass/criterion-with-extended-xpath.arazzo.json b/tests/schema/pass/criterion-with-extended-xpath.arazzo.json new file mode 100644 index 0000000..299c9a2 --- /dev/null +++ b/tests/schema/pass/criterion-with-extended-xpath.arazzo.json @@ -0,0 +1,35 @@ +{ + "arazzo": "1.1.0", + "info": { + "title": "Criterion with XPath", + "version": "1.3.0" + }, + "sourceDescriptions": [ + { + "name": "xmlAPI", + "url": "https://example.com/xml-api.yaml", + "type": "openapi" + } + ], + "workflows": [ + { + "workflowId": "xmlWorkflow", + "steps": [ + { + "stepId": "checkStatus", + "operationId": "statusCall", + "successCriteria": [ + { + "context": "$response.body", + "condition": "/Envelope/Status[text()='OK']", + "type": { + "type": "xpath", + "version": "xpath-31" + } + } + ] + } + ] + } + ] +} diff --git a/tests/schema/pass/minimal.arazzo.json b/tests/schema/pass/minimal.arazzo.json new file mode 100644 index 0000000..d41ad7b --- /dev/null +++ b/tests/schema/pass/minimal.arazzo.json @@ -0,0 +1,25 @@ +{ + "arazzo": "1.1.0", + "info": { + "title": "Minimal Arazzo Example", + "version": "1.0.0" + }, + "sourceDescriptions": [ + { + "name": "exampleAPI", + "url": "https://example.com/openapi.yaml", + "type": "openapi" + } + ], + "workflows": [ + { + "workflowId": "basicWorkflow", + "steps": [ + { + "stepId": "step1", + "operationId": "getUsers" + } + ] + } + ] +} diff --git a/tests/schema/pass/oauth-example.yaml b/tests/schema/pass/oauth-example.yaml index a68c9d7..56e7be1 100644 --- a/tests/schema/pass/oauth-example.yaml +++ b/tests/schema/pass/oauth-example.yaml @@ -1,4 +1,4 @@ -arazzo: 1.0.0 +arazzo: 1.1.0 info: title: Example OAuth service version: 1.0.0 diff --git a/tests/schema/pass/parameter-with-selector.arazzo.json b/tests/schema/pass/parameter-with-selector.arazzo.json new file mode 100644 index 0000000..e6d8c05 --- /dev/null +++ b/tests/schema/pass/parameter-with-selector.arazzo.json @@ -0,0 +1,36 @@ +{ + "arazzo": "1.1.0", + "info": { + "title": "Selector in Parameter", + "version": "1.0.1" + }, + "sourceDescriptions": [ + { + "name": "source1", + "url": "https://example.com/api.yaml", + "type": "openapi" + } + ], + "workflows": [ + { + "workflowId": "workflowWithSelector", + "steps": [ + { + "stepId": "stepA", + "operationId": "op1", + "parameters": [ + { + "name": "userId", + "in": "query", + "value": { + "expression": "$inputs.user", + "selector": "$.id", + "type": "jsonpath" + } + } + ] + } + ] + } + ] +} diff --git a/tests/schema/pass/payload-replacement-using-selector.arazzo.json b/tests/schema/pass/payload-replacement-using-selector.arazzo.json new file mode 100644 index 0000000..5054791 --- /dev/null +++ b/tests/schema/pass/payload-replacement-using-selector.arazzo.json @@ -0,0 +1,41 @@ +{ + "arazzo": "1.1.0", + "info": { + "title": "Payload Replacement", + "version": "1.2.0" + }, + "sourceDescriptions": [ + { + "name": "ordersAPI", + "url": "https://example.com/orders.yaml", + "type": "openapi" + } + ], + "workflows": [ + { + "workflowId": "replaceWorkflow", + "steps": [ + { + "stepId": "submitOrder", + "operationId": "createOrder", + "requestBody": { + "contentType": "application/json", + "replacements": [ + { + "target": "/order/items/0/id", + "value": { + "expression": "$steps.previous.outputs", + "selector": "$.itemId", + "type": { + "type": "jsonpath", + "version": "rfc9535" + } + } + } + ] + } + } + ] + } + ] +} diff --git a/tests/schema/pass/pet-coupons-example.yaml b/tests/schema/pass/pet-coupons-example.yaml index de6fe4c..5d0e80a 100644 --- a/tests/schema/pass/pet-coupons-example.yaml +++ b/tests/schema/pass/pet-coupons-example.yaml @@ -1,4 +1,4 @@ -arazzo: 1.0.0 +arazzo: 1.1.0 info: title: Petstore - Apply Coupons version: 1.0.0