Skip to content
axxbetadocs
v0.2.26next
GitHub

REST

View .mdOpen in Claude

Send HTTP requests to REST services, validate them against the services’ OpenAPI specifications, and assert on the responses.

Services. Register services with the <name> service with the following properties: (url, optional openapi). The first service registered in a scenario is the default one; the other steps name a service with on <name>.

Requests. Each service keeps its requests in the order they are added: a GET request to /path adds the first (default) request and a 2nd ordered POST request to /path the second. Header, payload, execution and response steps address a request with for 2nd ordered request / for 2nd ordered response (default: the first). A request is executed once; its response stays available to every later step.

Payloads. A payload starts from an OpenAPI content example (the named one, or the first in document order; externalValue examples are read relative to the specification) or from an empty template {}, and is edited with the payload property steps (JSONPath, typed values, null/undefined). application/x-www-form-urlencoded payloads are sent form-encoded.

Execution. Requests go through one HTTP client shared by the run (connections are reused and closed at the end), honor the step timeout, and do not verify TLS certificates unless packs.rest.tls.verify: true is set in axx.yaml. Without a Content-Type header a payload is sent with its payload step’s media type.

Redirects. A GET or HEAD request follows redirects (301, 302, 303, 307 and 308); a request with another method follows only 303 See Other, with a GET, as a browser does after a form. A request that follows a redirect has the response it leads to: the response steps check that one, and the redirect responses, with their Location and Set-Cookie headers, are not kept. The other redirects of a POST, PUT, PATCH or DELETE (301, 302, 307 and 308) are its response: check the status and the Location header, and send the request it leads to as the next ordered request.

Cookies. The pack keeps no cookies: a Set-Cookie response header is never sent back, not even to where a redirect leads, so no request carries a cookie from another scenario. Send a cookie with the Cookie request header: it goes along when the request follows a redirect on the same host or to a subdomain of it.

OpenAPI validation. When a service has an openapi specification (OpenAPI 3.0 or 3.1, a URL or a file; parsed once per run), each executed request and its response are validated after sending. Every finding has a key in the style of the swagger request validator (the one the WireMock extension uses), and a level:

  • ERROR (alias FAIL, the default for every key) fails the execute step, listing every error with its key;
  • WARN and INFO are logged on the step;
  • IGNORE drops the finding.

Levels come from openapi.levels in axx.yaml and are overridden per scenario with the OpenAPI validation levels are:. A key also sets every more specific key (validation.request.body covers validation.request.body.schema.required); the most specific configured key wins. A key must be one of the keys below, or a prefix of them: any other, in the step or in axx.yaml, is an error that names the closest keys.

Key Reported when
validation.request.path.missing no path of the specification matches the request path
validation.request.operation.notAllowed the path exists but not for the request method
validation.request.body.missing the operation requires a body and the request has none
validation.request.body.unexpected the request has a body the operation does not declare
validation.request.contentType.notAllowed the request Content-Type is not declared for the operation
validation.request.body.schema.{keyword} the request body violates a schema keyword (type, required, enum, format, pattern, minimum, maxLength, additionalProperties, oneOf, …)
validation.request.body.schema.invalidJson the request body cannot be parsed
validation.request.body.schema.processingError the request body schema cannot be compiled or the body cannot be read
validation.request.parameter.missing a required path parameter is missing
validation.request.parameter.query.missing a required query parameter is missing
validation.request.parameter.header.missing a required header parameter is missing
validation.request.parameter.cookie.missing a required cookie parameter is missing
validation.request.parameter.schema.{keyword} a parameter value violates its schema (type, enum, format, pattern, minimum, …)
validation.request.parameter.schema.invalidJson a JSON (content) parameter cannot be parsed
validation.request.parameter.schema.processingError a parameter’s schema cannot be compiled
validation.request.parameter.collection.invalidFormat an array or object parameter is serialized in the wrong style
validation.request.parameter.collection.tooManyItems an array parameter has more than maxItems items
validation.request.parameter.collection.tooFewItems an array parameter has fewer than minItems items
validation.request.parameter.collection.duplicateItems an array parameter with uniqueItems repeats an item
validation.request.parameter.{in}.invalid any other parameter problem; {in} is path, query, header or cookie
validation.request.security.missing the credentials a security requirement needs are absent
validation.request.security.invalid credentials are present but do not match the security scheme
validation.response.status.unknown the response status is not documented for the operation (and there is no default)
validation.response.contentType.notAllowed the response Content-Type is not declared for the status
validation.response.body.missing the response declares a body schema but has no body
validation.response.body.unexpected a response to HEAD has a body
validation.response.body.schema.{keyword} the response body violates a schema keyword
validation.response.body.schema.invalidJson the response body cannot be parsed
validation.response.body.schema.processingError the response body schema cannot be compiled or the body cannot be read
validation.response.header.missing a required response header is missing
validation.response.header.schema.{keyword} a response header value violates its schema
validation.request.unknownError anything else the validator reports about the request
validation.response.unknownError anything else the validator reports about the response

Schema keywords use the draft-4 names: const is reported as enum, exclusiveMinimum/exclusiveMaximum as minimum/maximum, unevaluatedProperties as additionalProperties. A schema failure that names no keyword is keyed unknownError (validation.request.body.schema.unknownError).

When a scenario fails, its failure context (rest) shows the last request and response (headers, bodies truncated to 2 KB) and the OpenAPI findings.

Add it to a project with axx pack add rest.

In axx.yaml, under packs.rest:

Setting Takes Values Default
openapi.levels Validation key -> ERROR (or FAIL), WARN, INFO or IGNORE. Merged over the top-level openapi.levels. names and values
tls.verify Verify TLS certificates. true, false false
Given the {word} service with the following properties:
| property | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Register a REST service: where its requests go, and the OpenAPI specification they are checked against.

  • The first service registered in a scenario is the default one.
  • With an openapi specification, every request executed and its response are validated against it, and request payloads can start from its examples.
  • Values can use ${env:…} and ${sys:…}, which are expanded.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
Property Takes Default
url the base URL requests go to, like http://localhost:8400; a request’s path is added to it required
openapi the service’s OpenAPI 3.0 or 3.1 specification: a URL, or a file of the project (relative to the resources directories or to axx.yaml’s directory)

Any other property fails the step.

Example:

Given the parcels service with the following properties:
| url | http://localhost:8400 |
| openapi | http://localhost:8400/openapi.json |
Given the OpenAPI validation levels[[ on {service}]] are:
| validation key | level |

The table may start with the row naming its columns, as above, or go straight to its rows.

Set the level of OpenAPI validation findings for this scenario, on the default or the named service.

  • A key also sets the keys below it: validation.request.body relaxes validation.request.body.schema.required too. The most specific key set wins.
  • The rows are merged over openapi.levels of axx.yaml.
  • The pack’s documentation lists the keys, and what each level does.
Parameter Takes For example
{service} the name of a REST service the scenario registered parcels

A row is a validation key and its level: ERROR (or FAIL), WARN, INFO or IGNORE. The key must be one the pack reports, or a prefix of such keys, like validation.request.body: any other fails the step, which names the closest keys.

Variants, the parts in [[...]] said or left out:

  • the OpenAPI validation levels are:
  • the OpenAPI validation levels on {service} are:

Example:

Given the OpenAPI validation levels are:
| validation.request.body.schema.maximum | IGNORE |
| validation.response.header.missing | WARN |
Given the OpenAPI validation levels on parcels are:
| validation.request.body.schema.required | WARN |
Given a(n) {word} request to {word}[[ on {service}]]

Add a request to the default or the named service: its method, and its path below the service’s url.

  • The path can have a query string, like /api/parcels?sender=kestrel-books. A whole URL replaces the service’s url.
  • This is the service’s first (default) request; the ordered form adds more.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • a(n) {word} request to {word}
  • a(n) {word} request to {word} on {service}

Example:

Given a GET request to /api/parcels/PX-1001
Given a DELETE request to /api/parcels/PX-1001 on parcels
Given a {ordinal} ordered {word} request to {word}[[ on {service}]]

Add the Nth request of a service. Requests are numbered in the order they are added: the 1st ordered request is the default request, and the Nth can only be added once N-1 exist.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{word} one word, with no spaces parcels, PX-4101
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • a {ordinal} ordered {word} request to {word}
  • a {ordinal} ordered {word} request to {word} on {service}

Example:

Given a 2nd ordered GET request to /api/parcels/PX-1001
Given a 1st ordered POST request to /api/parcels on parcels
Given the request header {word} is {string}[[ for {ordinal} ordered request]]

Set a request header.

  • Content-Type and Accept replace an earlier value; other headers may be added more than once, and are all sent.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.header.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the request header {word} is {string}
  • the request header {word} is {string} for {ordinal} ordered request

Example:

Given the request header Content-Type is 'application/json'
Given the request header {word} is {string} for[[ {ordinal} ordered]] request on {service}

rest.request.header on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.header.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request header {word} is {string} for request on {service}
  • the request header {word} is {string} for {ordinal} ordered request on {service}

Example:

Given the request header Accept is 'application/json' for 1st ordered request on parcels
Given the request headers[[ for {ordinal} ordered request]] are:
| header | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Set request headers, a row each.

  • A name may repeat. Like the single-header step, Content-Type and Accept replace an earlier value, and other headers are all sent.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.headers.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a header’s name and its value.

Variants, the parts in [[...]] said or left out:

  • the request headers are:
  • the request headers for {ordinal} ordered request are:

Example:

Given the request headers are:
| Accept | application/json |
| Accept-Language | de-DE |
Given the request headers for[[ {ordinal} ordered]] request on {service} are:
| header | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.request.headers on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.headers.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a header’s name and its value.

Variants, the parts in [[...]] said or left out:

  • the request headers for request on {service} are:
  • the request headers for {ordinal} ordered request on {service} are:

Example:

Given the request headers for request on parcels are:
| Content-Type | application/json |
| Accept | application/json |
Given a request payload using a(n) {mimeType} empty content template[[ for {ordinal} ordered request]]

Start the request payload from an empty JSON object, {}, for the payload property steps to fill.

  • It needs no OpenAPI specification.
  • With application/x-www-form-urlencoded, the properties are sent form-encoded, and nested objects and arrays as JSON text.
  • A request takes one payload step.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.payload.empty.on names a service.
Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} empty content template
  • a request payload using a(n) {mimeType} empty content template for {ordinal} ordered request

Example:

Given a request payload using an application/json empty content template
Given a request payload using a(n) {mimeType} empty content template for[[ {ordinal} ordered]] request on {service}

rest.request.payload.empty on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.payload.empty.

Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} empty content template for request on {service}
  • a request payload using a(n) {mimeType} empty content template for {ordinal} ordered request on {service}

Example:

Given a request payload using an application/json empty content template for request on parcels
Given a request payload using a(n) {mimeType} content example[[ named {string}]][[ for {ordinal} ordered request]]

Start the request payload from a request body example of the service’s OpenAPI specification.

  • With named '<name>' it is the example of that name; without, the first example in document order, or the media type’s single example.
  • The example is looked up under the operation that matches the request’s method and path, for the media type.
  • An example with an externalValue is read relative to the specification.
  • The service needs its openapi property, and the request must be added first.
  • A request takes one payload step.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.payload.example.on names a service.
Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} content example
  • a request payload using a(n) {mimeType} content example named {string}
  • a request payload using a(n) {mimeType} content example for {ordinal} ordered request
  • a request payload using a(n) {mimeType} content example named {string} for {ordinal} ordered request

Example:

Given a request payload using an application/json content example named 'Standard parcel'
Given a request payload using a(n) {mimeType} content example[[ named {string}]] for[[ {ordinal} ordered]] request on {service}

rest.request.payload.example on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.payload.example.

Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} content example for request on {service}
  • a request payload using a(n) {mimeType} content example named {string} for request on {service}
  • a request payload using a(n) {mimeType} content example for {ordinal} ordered request on {service}
  • a request payload using a(n) {mimeType} content example named {string} for {ordinal} ordered request on {service}

Example:

Given a request payload using an application/json content example for 1st ordered request on parcels
Given a request payload using a(n) {mimeType} {filepath} resource[[ for {ordinal} ordered request]]

Start the request payload from a file of the project, such as a fixture factory’s output: it is sent with the media type.

  • The file is found like other files steps name: relative to the resources directories, or to axx.yaml’s directory.
  • It is sent as it is, and a JSON payload can then be changed with the payload property steps. With application/x-www-form-urlencoded, the file is a JSON object whose properties are sent form-encoded.
  • It needs no OpenAPI specification.
  • A request takes one payload step.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.payload.resource.on names a service.
Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{filepath} a file of the project: a path relative to the feature file’s directory, the resources directories or axx.yaml’s directory (looked for in that order), or an absolute path, quoted when it has a space seeds/parcels.yaml, kafka/scan-delivered.json
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} {filepath} resource
  • a request payload using a(n) {mimeType} {filepath} resource for {ordinal} ordered request

Example:

Given a request payload using an application/json requests/order-7731.json resource
Given a request payload using a(n) {mimeType} {filepath} resource for[[ {ordinal} ordered]] request on {service}

rest.request.payload.resource on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.payload.resource.

Parameter Takes Values For example
{mimeType} a content type application/json, text/json, application/problem+json, application/x-www-form-urlencoded application/json
{filepath} a file of the project: a path relative to the feature file’s directory, the resources directories or axx.yaml’s directory (looked for in that order), or an absolute path, quoted when it has a space seeds/parcels.yaml, kafka/scan-delivered.json
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • a request payload using a(n) {mimeType} {filepath} resource for request on {service}
  • a request payload using a(n) {mimeType} {filepath} resource for {ordinal} ordered request on {service}

Example:

Given a request payload using an application/json requests/order-7732.json resource for 2nd ordered request on parcels
Given the request payload property {word} is {string}[[ for {ordinal} ordered request]]

Set a property of the request payload, by its JSONPath, like weightGrams, recipient.postcode or $.recipient.name.

  • A value in double quotes inside the quotes, like '"42"', is always a string.
  • Any other value takes the type of the property’s current value: a string, a boolean, an integer, a number, or an object or array parsed from JSON text.
  • A property that does not exist yet, or is null, takes the type its value reads as: true, 42, 1.5, {...}, [...], or else a string.
  • A property inside an object the payload lacks creates the object: recipient.name in a payload without recipient. A path through an array (items[2].sku) needs the array.
  • A payload step must come first.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.property.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the request payload property {word} is {string}
  • the request payload property {word} is {string} for {ordinal} ordered request

Example:

Given the request payload property sender is 'kestrel-books'
Given the request payload property {word} is {string} for[[ {ordinal} ordered]] request on {service}

rest.request.property on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.property.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request payload property {word} is {string} for request on {service}
  • the request payload property {word} is {string} for {ordinal} ordered request on {service}

Example:

Given the request payload property serviceLevel is 'EXPRESS' for request on parcels
Given the request payload properties[[ for {ordinal} ordered request]] are:
| JSONPath | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Set properties of the request payload, a row each, in order, like the single-property step.

  • null sets JSON null, and undefined removes the property, in any case.
  • "null" and "undefined", in double quotes, are the strings.
  • A property inside an object the payload lacks creates the object, so a table can list recipient.name and recipient.postcode on an empty payload.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.properties.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a property’s JSONPath and its value.

Variants, the parts in [[...]] said or left out:

  • the request payload properties are:
  • the request payload properties for {ordinal} ordered request are:

Example:

Given the request payload properties are:
| reference | PX-4101 |
| weightGrams | 1200 |
| recipient.postcode | "53111" |
Given the request payload properties for[[ {ordinal} ordered]] request on {service} are:
| JSONPath | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.request.properties on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.properties.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a property’s JSONPath and its value.

Variants, the parts in [[...]] said or left out:

  • the request payload properties for request on {service} are:
  • the request payload properties for {ordinal} ordered request on {service} are:

Example:

Given the request payload properties for 1st ordered request on parcels are:
| sender | lark-ceramics |
| recipient.street | undefined |
Given the request payload property {word} is null[[ for {ordinal} ordered request]]

Set an existing property of the request payload to JSON null.

  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.property.null.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the request payload property {word} is null
  • the request payload property {word} is null for {ordinal} ordered request

Example:

Given the request payload property recipient.street is null
Given the request payload property {word} is null for[[ {ordinal} ordered]] request on {service}

rest.request.property.null on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.property.null.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request payload property {word} is null for request on {service}
  • the request payload property {word} is null for {ordinal} ordered request on {service}

Example:

Given the request payload property recipient.street is null for request on parcels
When the[[ {ordinal} ordered]] request is executed[[ on {service}]]

Send a request, and keep its response for the response steps.

  • With an OpenAPI specification, the request and its response are validated after sending. Findings at level ERROR fail the step, which lists them all with their keys; WARN and INFO findings are logged.
  • The payload is sent as it is, or form-encoded for application/x-www-form-urlencoded.
  • Without a Content-Type header, the request has the payload’s media type; without an Accept header, */*.
  • A GET or HEAD request follows redirects, and a request with another method a 303 See Other (with a GET): the response steps then check the response it leads to. Other redirects are the response, with their Location header.
  • No cookies are kept: a Set-Cookie response header is not sent back. Send one with the Cookie request header.
  • The request honors the step timeout, and is executed once.
  • Without an ordinal it sends the service’s first (default) request; the 2nd ordered request, its second.
  • Without on {service} it uses the default service, the first one registered.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request is executed
  • the request is executed on {service}
  • the {ordinal} ordered request is executed
  • the {ordinal} ordered request is executed on {service}

Example:

When the request is executed
When the 2nd ordered request is executed on parcels
Then the[[ {ordinal} ordered]] response status code is {int}[[ on {service}]]

Check the HTTP status code of a response.

  • Without an ordinal it checks the response to the first (default) request; the 2nd ordered response, the response to the second.
  • Without on {service} it uses the default service, the first one registered.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{int} a whole number 200, 3
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response status code is {int}
  • the response status code is {int} on {service}
  • the {ordinal} ordered response status code is {int}
  • the {ordinal} ordered response status code is {int} on {service}

Example:

Then the response status code is 200
Then the 2nd ordered response status code is 201 on parcels
Then the response body contains {string}[[ for {ordinal} ordered response]]

Check that the response body contains the text.

  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.body.contains.on names a service.
Parameter Takes For example
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response body contains {string}
  • the response body contains {string} for {ordinal} ordered response

Example:

Then the response body contains 'already registered'
Then the response body contains {string} for[[ {ordinal} ordered]] response on {service}

rest.response.body.contains on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.body.contains.

Parameter Takes For example
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response body contains {string} for response on {service}
  • the response body contains {string} for {ordinal} ordered response on {service}

Example:

Then the response body contains 'already registered' for 2nd ordered response on parcels
Then the response header {word} is {string}[[ for {ordinal} ordered response]]

Check that a response header has the value.

  • The header’s name is matched in any case.
  • With the header repeated, one of its values must be the value.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.header.is.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response header {word} is {string}
  • the response header {word} is {string} for {ordinal} ordered response

Example:

Then the response header Content-Type is 'application/json'
Then the response header {word} is {string} for[[ {ordinal} ordered]] response on {service}

rest.response.header.is on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.header.is.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response header {word} is {string} for response on {service}
  • the response header {word} is {string} for {ordinal} ordered response on {service}

Example:

Then the response header Content-Type is 'application/json' for response on parcels
Then the response header {word} matches {pattern}[[ for {ordinal} ordered response]]

Check that a response header matches a regular expression.

  • The regular expression is in Java syntax, and must match the whole value.
  • With the header repeated, one of its values must match.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.header.matches.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{pattern} a regular expression (Java syntax) with no spaces, which matches the whole value PX-\d{4}, [A-Z]{2}-\d+
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response header {word} matches {pattern}
  • the response header {word} matches {pattern} for {ordinal} ordered response

Example:

Then the response header Content-Type matches ^application/json.*$
Then the response header {word} matches {pattern} for[[ {ordinal} ordered]] response on {service}

rest.response.header.matches on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.header.matches.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{pattern} a regular expression (Java syntax) with no spaces, which matches the whole value PX-\d{4}, [A-Z]{2}-\d+
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response header {word} matches {pattern} for response on {service}
  • the response header {word} matches {pattern} for {ordinal} ordered response on {service}

Example:

Then the response header Content-Type matches ^application/json$ for 1st ordered response on parcels
Then the response header {word} is missing[[ for {ordinal} ordered response]]

Check that the response has no header of that name.

  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.header.missing.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response header {word} is missing
  • the response header {word} is missing for {ordinal} ordered response

Example:

Then the response header Content-Length is missing
Then the response header {word} is missing for[[ {ordinal} ordered]] response on {service}

rest.response.header.missing on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.header.missing.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response header {word} is missing for response on {service}
  • the response header {word} is missing for {ordinal} ordered response on {service}

Example:

Then the response header Retry-After is missing for response on parcels
Then the response headers[[ for {ordinal} ordered response]] are:
| header | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Check response headers, a row each, like the single-header step.

  • A name may repeat.
  • Every row is checked, and every mismatch reported.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.headers.are.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a header’s name and the value it must have.

Variants, the parts in [[...]] said or left out:

  • the response headers are:
  • the response headers for {ordinal} ordered response are:

Example:

Then the response headers are:
| Content-Type | application/json |
| Location | /api/parcels/PX-4101 |
Then the response headers for[[ {ordinal} ordered]] response on {service} are:
| header | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.response.headers.are on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.headers.are.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a header’s name and the value it must have.

Variants, the parts in [[...]] said or left out:

  • the response headers for response on {service} are:
  • the response headers for {ordinal} ordered response on {service} are:

Example:

Then the response headers for 1st ordered response on parcels are:
| Content-Type | application/problem+json |
| Retry-After | 5 |
Then the response headers[[ for {ordinal} ordered response]] match:
| header | regular expression |

The table may start with the row naming its columns, as above, or go straight to its rows.

Check that response headers match regular expressions, a row each.

  • Each regular expression is in Java syntax, and must match the whole value.
  • Every row is checked, and every mismatch reported.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.headers.match.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a header’s name and a regular expression its value must match.

Variants, the parts in [[...]] said or left out:

  • the response headers match:
  • the response headers for {ordinal} ordered response match:

Example:

Then the response headers match:
| Content-Type | application/json.* |
| Location | /api/parcels/PX-[0-9]{4} |
Then the response headers for[[ {ordinal} ordered]] response on {service} match:
| header | regular expression |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.response.headers.match on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.headers.match.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a header’s name and a regular expression its value must match.

Variants, the parts in [[...]] said or left out:

  • the response headers for response on {service} match:
  • the response headers for {ordinal} ordered response on {service} match:

Example:

Then the response headers for response on parcels match:
| Retry-After | [0-9]+ |
Then the response headers[[ for {ordinal} ordered response]] are missing:
| header |

Check that the response has none of the headers the table names.

  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.headers.missing.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row names a header, in its first cell.

Variants, the parts in [[...]] said or left out:

  • the response headers are missing:
  • the response headers for {ordinal} ordered response are missing:

Example:

Then the response headers are missing:
| Retry-After |
| Set-Cookie |
Then the response headers for[[ {ordinal} ordered]] response on {service} are missing:
| header |

rest.response.headers.missing on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.headers.missing.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row names a header, in its first cell.

Variants, the parts in [[...]] said or left out:

  • the response headers for response on {service} are missing:
  • the response headers for {ordinal} ordered response on {service} are missing:

Example:

Then the response headers for response on parcels are missing:
| Retry-After |
Then the response payload property {word} is {string}[[ for {ordinal} ordered response]]

Check a property of a JSON response, by its JSONPath, like status, recipient.postcode or [?(@.sender=='kestrel-books')].reference.

  • An indefinite path, like a filter, reads as a list.
  • The response must be JSON: application/json, text/json or any +json type, whatever its charset.
  • A value is compared with its JSON type. Text, like REGISTERED, is a string, and so is a value in double quotes, like "42".
  • 42 is an integer, 42L a long and 1.5 a number. An integer never equals a decimal: 5 is not 5.0.
  • true and false are booleans. {...} and [...] are a JSON object and a JSON array; an object’s members may come in any order.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.property.is.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is {string}
  • the response payload property {word} is {string} for {ordinal} ordered response

Example:

Then the response payload property status is 'REGISTERED'
Then the response payload property {word} is {string} for[[ {ordinal} ordered]] response on {service}

rest.response.property.is on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.property.is.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is {string} for response on {service}
  • the response payload property {word} is {string} for {ordinal} ordered response on {service}

Example:

Then the response payload property status is 'REGISTERED' for 1st ordered response on parcels
Then the response payload property {word} is null[[ for {ordinal} ordered response]]

Check that a property of the response payload exists, and is JSON null.

  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.property.null.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is null
  • the response payload property {word} is null for {ordinal} ordered response

Example:

Then the response payload property lastLocation is null
Then the response payload property {word} is null for[[ {ordinal} ordered]] response on {service}

rest.response.property.null on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.property.null.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is null for response on {service}
  • the response payload property {word} is null for {ordinal} ordered response on {service}

Example:

Then the response payload property lastLocation is null for response on parcels
Then the response payload property {word} is undefined[[ for {ordinal} ordered response]]

Check that a property of the response payload does not exist.

  • An indefinite path always exists: it reads as a list, which may be empty.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.property.undefined.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is undefined
  • the response payload property {word} is undefined for {ordinal} ordered response

Example:

Then the response payload property recipient.street is undefined
Then the response payload property {word} is undefined for[[ {ordinal} ordered]] response on {service}

rest.response.property.undefined on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.property.undefined.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} is undefined for response on {service}
  • the response payload property {word} is undefined for {ordinal} ordered response on {service}

Example:

Then the response payload property recipient.street is undefined for 1st ordered response on parcels
Then the response payload property {word} matches {pattern}[[ for {ordinal} ordered response]]

Check that a property of the response payload is a string that matches a regular expression.

  • The regular expression is in Java syntax, and must match the whole value.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.property.matches.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{pattern} a regular expression (Java syntax) with no spaces, which matches the whole value PX-\d{4}, [A-Z]{2}-\d+
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} matches {pattern}
  • the response payload property {word} matches {pattern} for {ordinal} ordered response

Example:

Then the response payload property barcode matches ^PX[0-9]{11}$
Then the response payload property {word} matches {pattern} for[[ {ordinal} ordered]] response on {service}

rest.response.property.matches on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.property.matches.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{pattern} a regular expression (Java syntax) with no spaces, which matches the whole value PX-\d{4}, [A-Z]{2}-\d+
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the response payload property {word} matches {pattern} for response on {service}
  • the response payload property {word} matches {pattern} for {ordinal} ordered response on {service}

Example:

Then the response payload property barcode matches ^PX[0-9]{11}$ for response on parcels
Then the response payload properties[[ for {ordinal} ordered response]] are:
| JSONPath | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Check properties of a JSON response, a row each, like the single-property step.

  • null and undefined, in any case, check for JSON null and for no such property; "null", in double quotes, is the string.
  • Every row is checked, and every mismatch reported.
  • A value is compared with its JSON type. Text, like REGISTERED, is a string, and so is a value in double quotes, like "42".
  • 42 is an integer, 42L a long and 1.5 a number. An integer never equals a decimal: 5 is not 5.0.
  • true and false are booleans. {...} and [...] are a JSON object and a JSON array; an object’s members may come in any order.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.properties.are.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a property’s JSONPath and the value it must have.

Variants, the parts in [[...]] said or left out:

  • the response payload properties are:
  • the response payload properties for {ordinal} ordered response are:

Example:

Then the response payload properties are:
| reference | PX-4101 |
| status | REGISTERED |
| zone | DE-1 |
Then the response payload properties for[[ {ordinal} ordered]] response on {service} are:
| JSONPath | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.response.properties.are on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.properties.are.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a property’s JSONPath and the value it must have.

Variants, the parts in [[...]] said or left out:

  • the response payload properties for response on {service} are:
  • the response payload properties for {ordinal} ordered response on {service} are:

Example:

Then the response payload properties for 1st ordered response on parcels are:
| serviceLevel | STANDARD |
| recipient.name | Ada Lovelace |
| recipient.street | undefined |
Then the response payload properties[[ for {ordinal} ordered response]] match:
| JSONPath | regular expression |

The table may start with the row naming its columns, as above, or go straight to its rows.

Check that properties of the response payload are strings that match regular expressions, a row each.

  • Each regular expression is in Java syntax, and must match the whole value.
  • Every row is checked, and every mismatch reported.
  • Without an ordinal it checks the response to the first (default) request; for 2nd ordered response, the response to the second.
  • It uses the default service, the first one registered; rest.response.properties.match.on names a service.
Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

A row is a property’s JSONPath and a regular expression its value must match.

Variants, the parts in [[...]] said or left out:

  • the response payload properties match:
  • the response payload properties for {ordinal} ordered response match:

Example:

Then the response payload properties match:
| barcode | ^PX[0-9]{11}$ |
| signature | ^[0-9a-f]{64}$ |
Then the response payload properties for[[ {ordinal} ordered]] response on {service} match:
| JSONPath | regular expression |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.response.properties.match on a named service: for response on <service> addresses the service’s first (default) response, for 2nd ordered response on <service> its second one. Everything else works like rest.response.properties.match.

Parameter Takes For example
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

A row is a property’s JSONPath and a regular expression its value must match.

Variants, the parts in [[...]] said or left out:

  • the response payload properties for response on {service} match:
  • the response payload properties for {ordinal} ordered response on {service} match:

Example:

Then the response payload properties for 2nd ordered response on parcels match:
| [0].reference | PX-[0-9]{4} |
Given the {word} token with the following properties:
| property | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Register a bearer token under a name: a JSON Web Token Axx signs, or an OAuth 2.0 client credentials token Axx gets from a token endpoint.

  • A request uses it with the request is authorized with the {word} token; the steps of other packs that take header rows, like the websocket and sse packs, with ${token:<name>}.
  • A JSON Web Token is signed each time it is used, with iat and exp from then; the claims of the table add to them or replace them.
  • A client credentials token is got once for the run, and again once it expires.
  • Values expand ${env:..} and ${sys:..}; the token and its secrets are masked in logs and failures.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
Property Takes Values Default
algorithm how Axx signs a JSON Web Token HS256, HS384, HS512, RS256, ES256 HS256
key the secret an HS token is signed with, like ${env:SHOP_TOKEN_KEY}, or the PEM private key (a file of the project) of an RS or ES token
key id the kid in the token’s header
claim.<name> a claim of the token: a JSON value (true, 42, ["parcels:read"]) or text
expires in how long the token lasts from when it is used, like 5m 5m
token url an OAuth 2.0 token endpoint Axx gets a client credentials token from, instead of signing one
client id the client’s ID, for the token endpoint
client secret the client’s secret, like ${env:SHOP_CLIENT_SECRET}
scope the scopes asked for, separated by spaces
audience the API the token is for, for token endpoints that ask for one

Give a key for a token Axx signs, or a token url, client id and client secret for one it gets, not both.

Example:

Given the shop token with the following properties:
| key | ${env:SHOP_TOKEN_KEY} |
| claim.shop | maple-crafts |
Given the shop-system token with the following properties:
| token url | http://localhost:8400/oauth/token |
| client id | maple-crafts |
| client secret | ${env:SHOP_CLIENT_SECRET} |
| scope | parcels:read |

Since 0.1.5.

Given the request is authorized with the {word} token[[ for {ordinal} ordered request]]

Send the request with the token of that name: Authorization: Bearer <token>.

  • The token is had when the request is executed: a JSON Web Token is signed then.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.token.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the request is authorized with the {word} token
  • the request is authorized with the {word} token for {ordinal} ordered request

Example:

Given the request is authorized with the shop token

Since 0.1.5.

Given the request is authorized with the {word} token for[[ {ordinal} ordered]] request on {service}

rest.request.token on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.token.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request is authorized with the {word} token for request on {service}
  • the request is authorized with the {word} token for {ordinal} ordered request on {service}

Example:

Given the request is authorized with the shop token for 2nd ordered request on parcels

Since 0.1.5.

Given the request is signed in the {word} header[[ for {ordinal} ordered request]] with the following properties:
| property | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

Sign the request as webhooks are signed: an HMAC of its body, or of what the signs template gives, in the header.

  • The signature is made when the request is executed, over the body as it is sent.
  • sha256={signature} is GitHub’s form; t={timestamp},v1={signature} with {timestamp}.{body} signed, Stripe’s.
  • The key expands ${env:..}, and is masked.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.signed.on names a service.
Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
Property Takes Values Default
key the secret the signature is made with, like ${env:COURIER_WEBHOOK_KEY} required
algorithm the HMAC hmac-sha256, hmac-sha1, hmac-sha512 hmac-sha256
signs what is signed: a template of {body}, {timestamp} (Unix seconds), {method} and {path} (with the query), like {timestamp}.{body} {body}
encoding how the signature is written hex, base64 hex
value the header’s value: a template of {signature} and {timestamp}, like sha256={signature} or t={timestamp},v1={signature} {signature}
timestamp header a header that also carries {timestamp}, as Slack’s X-Slack-Request-Timestamp does

Variants, the parts in [[...]] said or left out:

  • the request is signed in the {word} header with the following properties:
  • the request is signed in the {word} header for {ordinal} ordered request with the following properties:

Example:

Given the request is signed in the X-Courier-Signature header with the following properties:
| key | ${env:COURIER_WEBHOOK_KEY} |
| value | sha256={signature} |

Since 0.1.5.

Given the request is signed in the {word} header for[[ {ordinal} ordered]] request on {service} with the following properties:
| property | value |

The table may start with the row naming its columns, as above, or go straight to its rows.

rest.request.signed on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.signed.

Parameter Takes For example
{word} one word, with no spaces parcels, PX-4101
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels
Property Takes Values Default
key the secret the signature is made with, like ${env:COURIER_WEBHOOK_KEY} required
algorithm the HMAC hmac-sha256, hmac-sha1, hmac-sha512 hmac-sha256
signs what is signed: a template of {body}, {timestamp} (Unix seconds), {method} and {path} (with the query), like {timestamp}.{body} {body}
encoding how the signature is written hex, base64 hex
value the header’s value: a template of {signature} and {timestamp}, like sha256={signature} or t={timestamp},v1={signature} {signature}
timestamp header a header that also carries {timestamp}, as Slack’s X-Slack-Request-Timestamp does

Variants, the parts in [[...]] said or left out:

  • the request is signed in the {word} header for request on {service} with the following properties:
  • the request is signed in the {word} header for {ordinal} ordered request on {service} with the following properties:

Example:

Given the request is signed in the Stripe-Signature header for request on parcels with the following properties:
| key | ${env:PAYMENTS_WEBHOOK_KEY} |
| signs | {timestamp}.{body} |
| value | t={timestamp},v1={signature} |

Since 0.1.5.

Given the request is signed as a standard webhook with the key {string}[[ for {ordinal} ordered request]]

Sign the request as a Standard Webhook (standardwebhooks.com): its webhook-id, webhook-timestamp and webhook-signature headers.

  • The key is whsec_ and the key in base64, as Standard Webhooks give it; it expands ${env:..}, and is masked.
  • The signature is made when the request is executed, over the body as it is sent.
  • Without an ordinal it applies to the service’s first (default) request; for 2nd ordered request, to its second.
  • It uses the default service, the first one registered; rest.request.webhook.on names a service.
Parameter Takes For example
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd

Variants, the parts in [[...]] said or left out:

  • the request is signed as a standard webhook with the key {string}
  • the request is signed as a standard webhook with the key {string} for {ordinal} ordered request

Example:

Given the request is signed as a standard webhook with the key '${env:SHOP_WEBHOOK_KEY}'

Since 0.1.5.

Given the request is signed as a standard webhook with the key {string} for[[ {ordinal} ordered]] request on {service}

rest.request.webhook on a named service: for request on <service> addresses the service’s first (default) request, for 2nd ordered request on <service> its second one. Everything else works like rest.request.webhook.

Parameter Takes For example
{string} text in double or single quotes, which the step leaves out "Get a quote", 'Express'
{ordinal} a position, counting from 1; an optional ordinal left out is the first 1st, 2nd
{service} the name of a REST service the scenario registered parcels

Variants, the parts in [[...]] said or left out:

  • the request is signed as a standard webhook with the key {string} for request on {service}
  • the request is signed as a standard webhook with the key {string} for {ordinal} ordered request on {service}

Example:

Given the request is signed as a standard webhook with the key '${env:SHOP_WEBHOOK_KEY}' for request on shops

Since 0.1.5.

Parameter Takes Values For example
{service} the name of a REST service the scenario registered parcels