Learn Arazzo by example
Boilerplate structure
Every Arazzo specification requires a few key components to get started. These elements form the basic structure that all Arazzo files must follow.
Spec
The arazzo
version declaration at the top of the file (e.g. arazzo: 1.0.1
)
Info
Similar to OpenAPI, Arazzo uses info
to describe the API. It also declares which version of Arazzo is used (even though only version 1.0.x
is available at the moment).
Source Descriptions
The sourceDescriptions
section is used to describe the sources of the API. It is a list of objects, each containing a name
and a url
(path to the OpenAPI file). It only supports openapi
type at the moment (but is expected to support more types such as asyncapi
in the future). We can supply an optional x-serverUrl
property to specify a specific server URL of the API.
Workflows
The workflows
section is used to define the workflows of the API. It is a list of objects, each containing a name
and a description
. We'll dive deeper into workflows in the next major section.
This specific workflow is based on the "Lost Invention Mission".
Steps
The steps
section is used to define the steps of a specific workflow. Each step contains a name
, a description
, and a request
object. The request
object contains the API call to be made. We'll dive deeper into steps in the next section. This specific workflow is based on the "Lost Invention Mission".
Workflow structure
An Arazzo can contain multiple workflows. This example Arazzo contains only a single workflow (with multiple steps).
Workflow: Lost Invention
This workflow is based on the "Lost Invention Mission".
Workflow: Lost Invention - Inputs
The inputs
section is used to define the inputs of a specific workflow. It is a json schema object describing each input. This specific API requires a token
input. We'll pass the token into the Arazzo workflow runner using an input parameter (or environment variable).
Workflow: Lost Invention - Parameters
The parameters
section is used to define the parameters of a specific workflow. It is a list of objects, each containing a name
, an in
property, and a value
property. The value in this case uses the prefixes the "Bearer " to the input parameter token
and passes it to the API as part of the Authorization
header.
Steps structure
A workflow can contain multiple steps. Each step contains a name
, a description
, and a reference to an operation in the API (such as an operationId
or path
).
Steps
The steps
section is used to define the steps of a specific workflow. The stepId
is required and used to uniquely identify the step. It's a good practice to give each step a meaningful description
.
Operation ID
The operationId
is the operation ID of the API call to be made. Arazzo has some flexibility in how it references the operation either by operationId
or an operationPath
. In this case, we're using the operationId
to reference the setAnchor
operation in the api-reference
API. Note that the operationId
is prefixed with the sourceDescription.name
(in this case, api-reference
) which allows Arazzo to disambiguate between operations with the same ID or path in different APIs.
Outputs
The outputs
section is used to define the outputs of a specific step. Output is only defined for passing data to another step. It does not describe the full API response.
In this case, we're using the anchor_id
output to pass the ID of the anchor to the next step. The value is $response.body#/id
which means that the value is the id
field in the response body.
The format of outputs is a map object where each key is the output name and the value follows a convention described in the Arazzo specification as a runtime expression.
Runtime expression following an ABNF syntax
expression = ( "$url" / "$method" / "$statusCode" / "$request." source / "$response." source / "$inputs." name / "$outputs." name / "$steps." name / "$workflows." name / "$sourceDescriptions." name / "$components." name / "$components.parameters." parameter-name)
parameter-name = name ; Reuses 'name' rule for parameter names
source = ( header-reference / query-reference / path-reference / body-reference )
header-reference = "header." token
query-reference = "query." name
path-reference = "path." name
body-reference = "body" ["#" json-pointer ]
json-pointer = *( "/" reference-token )
reference-token = *( unescaped / escaped )
unescaped = %x00-2E / %x30-7D / %x7F-10FFFF
; %x2F ('/') and %x7E ('~') are excluded from 'unescaped'
escaped = "~" ( "0" / "1" )
; representing '~' and '/', respectively
name = *( CHAR )
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
Request Body
The requestBody
section is used to define the request body of a specific step. You can supply a payload
object to pass data to the API. In this case, we're using the requestBody
to pass the timeline_id
and proposed_changes
to the API. You can "hardcode" the values or use the outputs from previous steps.
Using outputs from previous steps
In this exmaple, we're using the output from the setAnchorToCurrentTime
step to pass the anchor_id
to the returnToPresent
step.
Success criteria
Success criteria can be optionally defined for each step.
Success Criteria
The successCriteria
section is used to define the success criteria of a specific step. It is a list of objects, each containing a condition
and a context
. The condition
is a boolean expression that describes the success criteria. The context
is the context of the success criteria.
What can we do with Arazzo?
Respect is a powerful tool that can be used to test APIs described with Arazzo.
It checks that the API is working as expected by validating the API responses against the success criteria. Good news is that even if you don't take the time to define success criteria (or your success criteria are not exhaustive), Arazzo still validates the API responses (headers, status code, and body schemas) against the linked OpenAPI source description.
Try it out for yourself by running the workflow in Respect after you download these files into a folder (both the arazzo.yaml
and openapi.yaml
files), change into that folder and run the following command (no real token is needed for this example because the server is a mock server):
npx @redocly/cli@latest respect warp.arazzo.yaml --input token=your-token-here
Read more about Respect in Testing Arazzo Workflows.
# How to run workflows: npx @redocly/cli respect ./apis/warp.arazzo.yaml --input token=abc
arazzo: 1.0.1
info:
title: Warp API
version: 1.0.0
sourceDescriptions:
- name: api-reference
type: openapi
url: warp.openapi.yaml
x-serverUrl: "https://warp-multi-sidebars.redocly.app/_mock/apis/"
workflows:
- workflowId: missionLostInvention
summary: Lost invention
description: |-
Travel back to the year 1889 and retrieve the blueprint for Nikola Tesla’s lost invention before it’s destroyed in a mysterious fire.
inputs:
type: object
properties:
token:
type: string
format: password
description: JWT Bearer token
parameters:
- name: Authorization
in: header
value: "Bearer {$inputs.token}"
steps:
- stepId: setAnchorToCurrentTime
operationId: api-reference.setAnchor
description: Set an anchor to the current time.
outputs:
anchor_id: $response.body#/id
- stepId: createTimelineTo1889
operationId: api-reference.createTimeline
description: Create a timeline to 1889.
outputs:
timeline_id: $response.body#/id
- stepId: travelTo1889
operationId: api-reference.timeTravel
description: Travel to 1889.
requestBody:
payload:
destination: $steps.createTimelineTo1889.outputs.timeline_id
- stepId: findAndRegisterBlueprint
operationId: api-reference.registerItem
description: Find the blueprints. Then, register them using the `registerItem` API call.
requestBody:
payload:
description: Tesla's blueprint
outputs:
item_id: $response.body#/id
- stepId: avoidParadox
operationId: api-reference.checkParadox
description: Check for paradoxes.
requestBody:
payload:
timeline_id: $steps.createTimelineTo1889.outputs.timeline_id
proposed_changes:
- event: Sneak in to retrieve Tesla's blueprint
time: "1889-03-10T23:50:00Z"
- item_id: $steps.findAndRegisterBlueprint.outputs.item_id
successCriteria:
- condition: $statusCode == 200
- condition: $.is_stable == true
context: $response.body
type: jsonpath
- stepId: returnToPresent
operationId: api-reference.timeTravel
description: Return to the present.
requestBody:
payload:
destination: $steps.setAnchorToCurrentTime.outputs.anchor_id
items:
- $steps.findAndRegisterBlueprint.outputs.item_id