diff --git a/dsl-reference.md b/dsl-reference.md
index d2da159b..54cc57f4 100644
--- a/dsl-reference.md
+++ b/dsl-reference.md
@@ -50,6 +50,7 @@
+ [Duration](#duration)
+ [HTTP Response](#http-response)
+ [HTTP Request](#http-request)
+ + [URI Template](#uri-template)
## Abstract
@@ -83,7 +84,7 @@ Documents the workflow definition.
| dsl | `string` | `yes` | The version of the DSL used to define the workflow. |
| namespace | `string` | `yes` | The workflow's namespace.
|
| name | `string` | `yes` | The workflow's name.
|
-| version | `string` | `yes` | The workflow's [semantic version]
+| version | `string` | `yes` | The workflow's [semantic version](https://semver.org/) |
| title | `string` | `no` | The workflow's title. |
| summary | `string` | `no` | The workflow's Markdown summary. |
| tags | `map[string, string]` | `no` | A key/value mapping of the workflow's tags, if any. |
@@ -279,7 +280,7 @@ do:
Serverless Workflow defines several default functions that **MUST** be supported by all implementations and runtimes:
-- [AsyncAPI](#asyncapi)
+- [AsyncAPI](#asyncapi-call)
- [gRPC](#grpc-call)
- [HTTP](#http-call)
- [OpenAPI](#openapi-call)
@@ -528,9 +529,9 @@ Allows workflows to iterate over a collection of items, executing a defined set
| Name | Type | Required | Description|
|:--|:---:|:---:|:---|
| for.each | `string` | `no` | The name of the variable used to store the current item being enumerated.
Defaults to `item`. |
-| for.in | `string` | `yes` | A [runtime expression](#runtime-expressions) used to get the collection to enumerate. |
+| for.in | `string` | `yes` | A [runtime expression](./dsl.md/#runtime-expressions) used to get the collection to enumerate. |
| for.at | `string` | `no` | The name of the variable used to store the index of the current item being enumerated.
Defaults to `index`. |
-| while | `string` | `no` | A [runtime expression](#runtime-expressions) that represents the condition, if any, that must be met for the iteration to continue. |
+| while | `string` | `no` | A [runtime expression](./dsl.md/#runtime-expressions) that represents the condition, if any, that must be met for the iteration to continue. |
| do | [`task`](#task) | `yes` | The task to perform for each item in the collection. |
##### Examples
@@ -601,7 +602,6 @@ do:
room: ${ .room.number }
```
-
#### Listen
Provides a mechanism for workflows to await and react to external events, enabling event-driven behavior within workflow systems.
@@ -1073,7 +1073,7 @@ Defines an external resource.
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
| name | `string` | `no` | The name, if any, of the defined resource. |
-| uri | `string` | `yes` | The URI at which to get the defined resource. |
+| uri | [`uri-template`](#uri-template) | `yes` | The URI at which to get the defined resource. |
| authentication | [`authentication`](#authentication) | `no` | The authentication policy, or the name of the authentication policy, to use when fecthing the resource. |
##### Examples
@@ -1208,8 +1208,8 @@ Defines the fundamentals of an 'oauth2' authentication
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
-| authority | `string` | `yes` | The URI that references the OAuth2 authority to use. |
-| grant | `string` | `yes` | The grant type to use.
+| authority | [`uri-template`](#uri-template) | `yes` | The URI that references the OAuth2 authority to use. |
+| grant | `string` | `yes` | The grant type to use. |
| client.id | `string` | `yes` | The client id to use. |
| client.secret | `string` | `no` | The client secret to use, if any. |
| scopes | `string[]` | `no` | The scopes, if any, to request the token for. |
@@ -1346,7 +1346,7 @@ Defines the [Problem Details RFC](https://datatracker.ietf.org/doc/html/rfc7807)
| Property | Type | Required | Description |
|----------|:----:|:--------:|-------------|
-| type | `string` | `yes` | A URI reference that identifies the [`error`](#error) type.
For cross-compatibility concerns, it is strongly recommended to use [Standard Error Types](#standard-error-types) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
+| type | [`uri-template`](#uri-template) | `yes` | A URI reference that identifies the [`error`](#error) type.
For cross-compatibility concerns, it is strongly recommended to use [Standard Error Types](#standard-error-types) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
| status | `integer` | `yes` | The status code generated by the origin for this occurrence of the [`error`](#error).
For cross-compatibility concerns, it is strongly recommended to use [HTTP Status Codes](https://datatracker.ietf.org/doc/html/rfc7231#section-6) whenever possible.
Runtimes **MUST** ensure that the property has been set when raising or escalating the [`error`](#error). |
| instance | `string` | `yes` | A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) used to reference the component the [`error`](#error) originates from.
Runtimes **MUST** set the property when raising or escalating the [`error`](#error). Otherwise ignore. |
| title | `string` | `no` | A short, human-readable summary of the [`error`](#error). |
@@ -1685,4 +1685,22 @@ method: get
uri: https://petstore.swagger.io/v2/pet/1
headers:
Content-Type: application/json
-```
\ No newline at end of file
+```
+
+### URI Template
+
+The DSL has limited support for URI template syntax as defined by [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570). Specifically, only the [Simple String Expansion](https://datatracker.ietf.org/doc/html/rfc6570#section-3.2.2) is supported, which allows authors to embed variables in a URI.
+
+To substitute a variable within a URI, use the `{}` syntax. The identifier inside the curly braces will be replaced with its value during runtime evaluation. If no value is found for the identifier, an empty string will be used.
+
+This has the following limitations compared to runtime expressions:
+
+- Only top-level properties can be interpolated within strings, thus identifiers are treated verbatim. This means that `{pet.id}` will be replaced with the value of the `"pet.id"` property, not the value of the `id` property of the `pet` property.
+- The referenced variable must be of type `string`, `number`, `boolean`, or `null`. If the variable is of a different type an error with type `https://https://serverlessworkflow.io/spec/1.0.0/errors/expression` and status `400` will be raised.
+- [Runtime expression arguments](./dsl.md#runtime-expression-arguments) are not available for string substitution.
+
+#### Examples
+
+```yaml
+uri: https://petstore.swagger.io/v2/pet/{petId}
+```
diff --git a/schema/workflow.yaml b/schema/workflow.yaml
index c4fd8a69..31fece1c 100644
--- a/schema/workflow.yaml
+++ b/schema/workflow.yaml
@@ -730,7 +730,7 @@ $defs:
properties:
authority:
type: string
- format: uri
+ format: uri-template
description: The URI that references the OAuth2 authority to use.
grant:
type: string
@@ -940,14 +940,14 @@ $defs:
externalResource:
oneOf:
- type: string
- format: uri
+ format: uri-template
- title: ExternalResourceURI
type: object
unevaluatedProperties: false
properties:
uri:
type: string
- format: uri
+ format: uri-template
description: The endpoint's URI.
authentication:
$ref: '#/$defs/referenceableAuthenticationPolicy'