Last updated

Source descriptions and references

In Arazzo, sourceDescriptions is your bridge to the outside world—specifically, to the OpenAPI files (or even other Arazzo files) that define the APIs you're working with. When you're bending time with the Warp API, you don't want to rewrite every endpoint from scratch. Instead, sourceDescriptions lets you link to existing definitions and reference them dynamically. Let's explore its role, how to use $ref and runtime expressions, and some best practices for keeping multiple sources organized.

The role of sourceDescriptions

The sourceDescriptions section is like a directory of API blueprints. It tells Arazzo where to find the OpenAPI specs your workflows depend on—like the Warp API's time-travel endpoints. Each entry in this array connects your steps to the operations they'll call, ensuring your workflows stay lean and reusable.

Here's a basic setup for the Warp API:

arazzo: "1.0.1"
info:
  title: "Time Travel Ops"
  version: "1.0.0"
sourceDescriptions:
  - name: "warpApi"
    url: "https://api.warp.example.com/v1/openapi.yaml"
    type: "openapi"
workflows:
  - workflowId: "quickJump"
    summary: "A fast time hop"
    steps:
      - stepId: "travel"
        operationId: "warpApi.timeTravel"

What's happening?

  • name: warpApi is an alias you'll use to reference this source.
  • url: Points to the OpenAPI file (e.g., openapi.yaml from Warp).
  • type: Specifies it's an openapi file (you can also link to other Arazzo files with arazzo).

When a step uses operationId: "warpApi.timeTravel", Arazzo knows to look in that OpenAPI file for the timeTravel operation. This keeps your Arazzo file focused on how to use the API, not what it is.

Using $ref and runtime expressions

Arazzo takes referencing up a notch with $ref and runtime expressions, letting you pull in data dynamically. While $ref is more common in OpenAPI for static reuse, Arazzo leans on runtime expressions (like $response.body.id) for live data flow. However, $ref can still play a role in sourceDescriptions.

sourceDescriptions:
  - name: "warpApi"
    url: "https://api.warp.example.com/v1/openapi.yaml"
  - name: "commonAnchors"
    url: "./anchors.yaml"
    type: "arazzo"
components:
  anchor:
    $ref: "commonAnchors#/components/anchors/homeBase"
Here, commonAnchors is another Arazzo file with predefined anchors, and $ref pulls one into your components for reuse.
Runtime Expressions
More often, you'll use runtime expressions in steps to grab live data. From our Warp example:
yaml
steps:
  - stepId: "setAnchor"
    operationId: "warpApi.setAnchor"
    outputs:
      anchorId: "$response.body.id"
  - stepId: "jump"
    operationId: "warpApi.timeTravel"
    parameters:
      body:
        destination: "$steps.setAnchor.outputs.anchorId"

The $steps.setAnchor.outputs.anchorId expression dynamically grabs the anchor ID from the previous step's response—no static $ref needed here.

Referencing across sources

When a step calls an operation, you can prefix the operationId with the source name (e.g., warpApi.timeTravel) if multiple sources are in play. Alternatively, use operationPath for precision:

- stepId: "jump"
  operationPath: "warpApi#/paths/~1travels/post"

This points directly to the /travels POST endpoint in the Warp API's OpenAPI file.

Best practices for multiple API sources

Managing several sourceDescriptions—say, Warp's core API plus a monitoring service—can get tricky. Here's how to keep it clean:

  1. Use Descriptive Names: Pick names like warpCore or timelineMonitor over generic api1. It's clearer when referencing (e.g., warpCore.timeTravel).
  2. Centralize Sources: Host OpenAPI files in a consistent place (e.g., a docs server or Git repo) and use absolute URLs. Local files (./openapi.yaml) work for testing but can break in production.
    sourceDescriptions:
    - name: "warpCore"
        url: "https://api.warp.example.com/v1/openapi.yaml"
    - name: "warpMonitor"
        url: "https://monitor.warp.example.com/openapi.yaml"
  3. Version Control: Include version info in URLs or filenames (e.g., openapi-v1.yaml) to avoid surprises when APIs update.
  4. Avoid Overlap: If two sources define similar operationId (e.g., timeTravel), use operationPath or unique name prefixes to disambiguate.
  5. Test References: Validate that every operationId or operationPath matches an existing operation—tools like Redocly CLI (redocly lint) can help.

Why it matters

Source descriptions keeps your Arazzo workflows modular and connected to the broader API ecosystem. With Warp, you might link to timeline management, travel ops, and paradox checks—all without duplicating definitions. Throw in $ref for static reuse and runtime expressions for dynamic flow, and you've got a system that's both flexible and powerful. Next time, we'll dig into success criteria—because even time travelers need to know if their jump landed smoothly!