Defining Integrations as Code

Overview

There are many ways to create Prismatic integrations. You can assemble one through the web app, through the Prismatic CLI, through calls to the Prismatic API, or by defining your integration as code in a YAML file.

We recommend that you assemble your first few integrations through the web app so you can acquaint yourself with triggers, action steps, inputs and outputs, configuration variables and credentials, but once you feel comfortable with these concepts we encourage you to explore creating integrations programmatically.

Anything you can add to an integration in the web app, you can add through YAML as well. Using YAML syntax, you can define an entire integration, including its trigger and action steps, and how data flows between the steps.

Advantages of Writing Integrations as Code

If you are a developer, regardless of if you fall on the Vim, Emacs, or VSCode side of the editor war, you are likely more productive in a text editor than you are in a web browser. You can grep over a codebase and make changes to your integrations more quickly in an editor than you can in a browser. In addition to yielding greater productivity, writing integrations as code gives you:

  • A faster feedback loop. Make significant changes to multiple steps of an integration and test the integration from your terminal - no clicking required!
  • The ability to store integrations in your source repository. Your integration can go through whatever spec writing, development, code review, and deployment cycle you currently use. You can develop your integration in tandem with your core product and its APIs.
  • The option to update integrations as part of your CI/CD Pipeline. Is your integration dependent on updates to your APIs? You can plug your YAML-defined integrations into your CI/CD pipeline, so integrations are deployed alongside the rest of your code base.

Integration YAML File Anatomy

A YAML-defined integration contains five required sections: name, description, trigger, requiredConfigVars, and steps.

Integration YAML File Anatomy
---
name: String
description: (optional) String
trigger:
name: String
description: (optional) String
outputs: (optional)
- OutputKey: OutputValue
schedule: (optional) CronString
requiredConfigVars: (optional)
RequiredConfigVarName: RequiredConfigVarValue
steps:
- name: String
description: (optional) String
action:
key: String
componentKey: String
inputs: (optional)
- InputKey: InputValue
outputs: (optional)
- OutputKey: OutputValue
  • name is a brief unique identifier, and the name of the integration. For example, "Queue 3D Print Job".
  • description is an optional longer explanation of what the integration does. Your team members in the web app can search for integrations by name or description. For example, "This integration converts a completed .rocket file to AutoCAD format and queues a 3D print job."
  • trigger defines how the integration should be invoked. It takes a required name, and optional description, outputs, and schedule, each of which are described in more detail below.
  • requiredConfigVars describes the configuration variable keys and their default values that your integration uses.
  • steps is an ordered list of actions your integration will execute. Each step takes a required name, an action to execute, and optional description and step inputs and outputs, described in more detail below.

Integration Triggers in YAML

An integration trigger defines when an instance of an integration should run. The integration can be triggered by a webhook, or on a schedule similar to a cron job. If a schedule is specified, the trigger will run on a schedule. If schedule is omitted, a webhook trigger will be created.

For More Information: Integration Triggers

Specifying a Scheduled Trigger in YAML

You can run integrations on a schedule using cron notation. For example, if you want instances of an integration to run at 03:00 AM every Sunday and Wednesday morning, you can configure a trigger to run at that time:

trigger:
name: my_trigger
description: Runs at 03:00 every Monday and Thursday
schedule: '"0 3 * * 1,4"'

For More Information: Schedule Triggers

Capturing Webhook Trigger Output in YAML

If your trigger is invoked by a webhook, the body and header information of that output is accessible by referencing outputs.TRIGGER_NAME.all.{body,headers}. To simplify output variable names, you can capture specific output and assign that to an output variable. In this example, suppose a webhook contained a JSON payload body of {"customer":{"id":123}}. You can capture that 123 value like so:

trigger:
name: my_trigger
description: Kicks off the integration
outputs:
customerId: body.customer.id

Subsequent steps can then reference outputs.my_trigger.customerId.

For More Information: Webhook Triggers

Configuration Variables in YAML

Configuration variables are defined in the requiredConfigVars portion of integration YAML files as key-value pairs:

requiredConfigVars:
myEndpoint: https://my.company.com/api
customerId: A99E0DE1-6187-4BF7-A873-288F34E0BB03

Steps can reference these configuration variables using configVars.VARIABLE_NAME (e.g. configVars.customerId).

For More Information: Config Vars, Config Vars in Integrations

Integration Action Steps in YAML

Integrations are comprised of multiple steps. A step requires a name (referenceable name), and an action to execute. Optionally, a step can take a description, and can reference inputs and produce outputs.

The step's action takes a key of an action, and the action's componentKey. The componentKey is required, since action keys are not necessarily unique (AWS S3 and Azure file might both have a gitObject action). Action keys and component keys can be found using the Prismatic CLI components:actions:list subcommand.

For example, if you want to add a step that lists all objects of an S3 bucket, you can run this to get the action's key and componentKey:

$ prism components:actions:list --columns key,componentKey,label,description | grep s3
copyObject aws_s3 Copy an object Copy an object in S3 from one location to another
deleteObject aws_s3 Delete an Object in a Bucket Delete an Object within an S3 Bucket
getObject aws_s3 Get an object Get the contents of an object
listObjects aws_s3 List Objects in a Bucket List Objects in a Bucket
putObject aws_s3 Put an object Write an object to S3

You can then use those keys in a step:

steps:
- name: get_rocket_schematic_files
description: Get a list of all rocket schematics in our S3 bucket
action:
key: listObjects
componentKey: aws_s3
inputs:
awsRegion: '"us-east-1"'
bucket: configVars.myBucketName
JSONata syntax in inputs and outputs

Notice that us-east-1 is wrapped in single and double quotes, and configVars.myBucketName is not wrapped in quotes at all. This is because we want configVars.myBucketName to be interpreted as variable, and us-east-1 as a string. Due to how YAML interprets strings, awsRegion: "us-east-1" is equivalent to awsRegion: us-east-1. We need to explicitly state that the quotation marks are intentional - we do that by wrapping quotation marks within quotation marks.

Multi-line Values in YAML

YAML syntax supports multiline strings, so Prismatic does, too. Multiline strings are especially helpful if you use a code component. Your code component code can be written entirely in-line:

steps:
- name: return_hello_world
description: Return the string "Hello World"
action:
key: runCode
componentKey: code
inputs:
code: |
'module.exports = async (context, params) => {
return {
message: "Hello, World",
};
};'

Importing a YAML-Defined Integration

To import a YAML-defined integration, use the Prismatic CLI integrations:import subcommand:

prism integrations:import --path path/to/your-integration.yaml

Exporting an Integration as YAML

An existing integration that was built via YAML or in the integration designer can be exported to a YAML file using the Prismatic CLI integrations:export subcommand:

prism integrations:export SW50ZWdyYXRpb246EXAMPLE > my-integration.yaml

Example Integration in YAML

The integration from the getting started tutorial pulled down "TODO" items from a list, and posted a message to Slack. That entire integration can be defined in a short YAML file:

name: My First Integration
description: My first foray into Prismatic
trigger:
name: trigger
description: Kicks off an integration
requiredConfigVars:
mySlackWebhook: https://hooks.slack.com/services/REPLACE/THIS/TEXT
steps:
- name: fetch_todos
description: Fetch a list of TODO items
action:
key: httpGet
componentKey: http
inputs:
url: '"https://jsonplaceholder.typicode.com/todos"'
responseType: '"json"'
- name: post_slack_message
description: Post a message to slack of the form "X of your Y tasks are marked complete."
action:
key: postSlackMessage
componentKey: slack
inputs:
webhookUrl: configVars.mySlackWebhook
message: '$count(outputs.fetch_todos.all[completed]) & " of your " & $count(outputs.fetch_todos.all) & " tasks are marked complete."'

Opening up the web app, we see that this YAML-defined integration created the appropriate trigger, steps, config vars and inputs.

Further Reading

After you feel comfortable defining basic integrations with YAML, we recommend you check out our Writing an Integration in YAML with Trigger Payloads, Inputs, and Outputs quickstart, where we examine how to handle webhook trigger payloads, code components, and knitting inputs and outputs throughout a YAML-defined integration.

Last updated on