Pipeline resolvers

The Tailor Platform provides GraphQL APIs to access and manipulate your data. While the GraphQL APIs cover many use cases, more complex ones warrant the chaining of multiple operations. Pipeline resolvers provide a way to chain queries while performing data transformations at each step.

Overview

GraphQLGatewayGraphQLInterfaceResolverPre ScriptPre ScriptGraphQL RequestPost ScriptPipeline AargsargsargsargsPipeline BargsPipeline ...argsPost ScriptargsContextPipelines executionsresultsargsarguments of resolverPipeline A's resultsPipeline B's resultsPipeline ... resultsdata(can be set freely)Subgraph

When a request resolves to a pipeline, it goes through its steps sequentially. As it proceeds through those, the results of each step are passed as arguments to the next. Each step can use the results of its caller using args, or use the results of any prior step using context.

Pipeline file

You can create a new pipeline using a tailor_pipeline resource and reference it in the workspace. The required fields for the pipeline service are workspace_id and namespace. To add a new pipeline resolver, we recommend you add a file named pipeline_<resolver_name> in the application folder.

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;tailor_pipeline&quot;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;ims&quot;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">workspace_id</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">tailor_workspace.ims.id</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">namespace</span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;ims&quot;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">common_sdl</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  # here we define common types used in the pipeline</span></span>
<span><span style="color: var(--shiki-token-string)">  type Query {</span></span>
<span><span style="color: var(--shiki-token-string)">    dummy: Boolean</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-token-string)">  type Mutation {</span></span>
<span><span style="color: var(--shiki-token-string)">    dummy: Boolean</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-token-string)">  EOF</span></span>
<span><span style="color: var(--shiki-token-string)">}</span></span>
<span></span>

Resolvers are defined in a file (typically services/pipeline/pipeline.cue) written in CUE. See CUE basics for more information.

The pipeline file imports the pipeline type definitions:

<span><span style="color: var(--shiki-token-keyword)">package</span><span style="color: var(--shiki-color-text)"> pipeline</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">github.com/tailor-platform/tailorctl/schema/v2/pipeline</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/{APPLICATION_NAME}/environment</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">tailor.build/{APPLICATION_NAME}/services/pipeline/resolvers</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">)</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">pipeline.#Spec </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Namespace: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">my-pipeline</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Resolvers: [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// this is where we will add pipeline resolvers </span></span>
<span><span style="color: var(--shiki-color-text)">    resolvers.{PIPELINE_RESOLVER_NAME},</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Definition

The pipeline configuration file contains the definitions that the pipeline implementations will expect and produce.

Properties

workspace_id: The ID of the workspace containing the app (required).

namespace: The namespace for the app's pipelines (required).

Example

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;tailor_pipeline&quot;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;ims&quot;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">workspace_id</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">tailor_workspace.ims.id</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">namespace</span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;ims&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

The pipeline manifest object contains the type definitions that the pipeline implementations will expect and produce.

Properties

Namespace: The namespace for the project's pipelines (required).

Resolvers: The pipelines implementations.

Example

<span><span style="color: var(--shiki-color-text)">pipeline.#Spec </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Namespace: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">my-pipeline</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Resolvers: [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// this is where we will add pipeline resolvers </span></span>
<span><span style="color: var(--shiki-color-text)">    resolvers.{PIPELINE_RESOLVER_NAME},</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Caveats

  • Subscription operations are not supported, only Mutation and Query may be used.
  • The name of the types MUST NOT collide with the existing types' (e.g. User, etc.) as well as auto-generated operations (e.g. createUser, etc.).

Resolver

The pipeline_resolver resource represents a pipeline resolver and features the implementations of the pipelines.

Properties

PropertyTypeRequiredDescription
namestringYesThe name of this pipeline resolver
namespacestringYesThe namespace of the pipeline resolver
workspace_idstringYesThe ID of the workspace that the pipeline resolver belongs to
sdlstringYesThe SDL for this pipeline resolver
descriptionstringNoThe description of the pipeline
stepsarrayYesA list that contains pipeline steps
publish_execution_eventsbooleanNoMust be set to true to enable the publishing of pipeline execution events to the executor service

Scripting Properties

PropertyTypeScripting LanguageDescription
authorizationobjectCELThe authorization rules for the pipeline. You can set this field using insecure or user properties such as id, type (which can be either user or machine_user), workspace_id and attributes (an array of UUIDs configured in the attributes in the Auth service)
pre_hookstringJavaScriptA script block where the input that will be passed to the pipeline can be validated and transformed
pre_scriptstringCELA script block where the input that will be passed to the pipeline can be transformed
post_scriptstringCELA script block where the result of the pipeline can be transformed. NOTE: The result of the last step of a pipeline cannot be a scalar value. If you want the pipeline to return such a value, use post_script to extract the value you need
post_hookstringJavaScriptA script block where the result of the pipeline can be validated and transformed

Refer to the Tailor Platform Provider documentation for more details on pipeline resolver properties.

The Resolver object features the implementations of the pipelines.

Properties

PropertyTypeRequiredDescription
NamestringYesThe pipeline object name
DescriptionstringYesThe description of the pipeline
InputsarrayNoThe input types of the pipeline. See the following section.
ResponseobjectNoThe response type of the pipeline. See the following section.
OperationTypestringNoThe operation type is either query or mutation. If no value is specified, it defaults to mutation if the operation in the pipelines is a mutation; otherwise, it defaults to query
PipelinesarrayYesA list that contains pipeline steps
PublishExecutionEventsbooleanNoMust be set to true to enable the publishing of pipeline execution events to the executor service

Scripting Properties

PropertyTypeScripting LanguageDescription
AuthorizationobjectCELThe authorization rules for the pipeline. You can set this field using pipeline.#AuthInsecure, pipeline.#AuthLoggedInUser, or user properties such as id, type (which can be either user or machine_user), workspace_id and attributes (an array of UUIDs configured in the AttributesFields in the Auth service)
PreHookstringJavaScriptA script block where the input that will be passed to the pipeline can be validated and transformed
PreScriptstringCELA script block where the input that will be passed to the pipeline can be transformed
PostScriptstringCELA script block where the result of the pipeline can be transformed. NOTE: The result of the last step of a pipeline cannot be a scalar value. If you want the pipeline to return such a value, use PostScript to extract the value you need
PostHookstringJavaScriptA script block where the result of the pipeline can be validated and transformed

Inputs and Response

The Inputs and Response properties are used to define the input and output types of the pipeline. Inputs accepts an array of Field objects while Response accepts only a single Field object.

Field properties

  • Name: The name of the field.
  • Type: The type of the field. You can define your own type or use any of the existing schema types.
  • Required: Whether the field is required or not.
  • Array: Whether the field is an array or not.
  • Description: Description of the field.

Type properties

  • Name: The name of the type.
  • Fields: An array of Field property.

Schema types

Scalar Types

  • String
  • Int
  • Float
  • Boolean
  • ID

Custom Scalar Types

  • Date
  • DateTime
  • Time

Example

<span><span style="color: var(--shiki-color-text)">EmployeeType: pipeline.#EnumType </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">EmployeeType</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Values: [</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">MANAGER</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">STAFF</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">bindUserToContractInput: {</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">your_defined_input_type</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Fields: [</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">userID</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">       Type: pipeline.ID</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">User ID</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">code</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">         Type: pipeline.Int</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Contract code</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">bindDate</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">     Type: pipeline.Date</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">bindTime</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">     Type: pipeline.Time</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">bindDateTime</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Type: pipeline.DateTime</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">roleType</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">     Type: EmployeeType</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required:  </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Employee type</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">bindUserToContractOutput: {</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">your_defined_response_type</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Fields: [</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">userID</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)">       Type: pipeline.ID }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">bindUserToContract: pipeline.#Resolver </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">bindUserToContract</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Bind a User to a Contract</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Inputs: [</span></span>
<span><span style="color: var(--shiki-color-text)">    { Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">input</span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Required: </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> Type: bindUserToContractInput }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">  PublishExecutionEvents: </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">  Response: { Type: bindUserToContractOutput }</span></span>
<span><span style="color: var(--shiki-color-text)">  OperationType: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">mutation</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Authorization: pipeline.#AuthInsecure</span></span>
<span><span style="color: var(--shiki-color-text)">  PreScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Pipelines: []</span></span>
<span><span style="color: var(--shiki-color-text)">  PostScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

In the above example, after the pipeline bindUserToContract execution, the event pipeline.resolver.executed is published. The Executor service then processes this event and initiates jobs defined based on it.

Execution Order (Resolver level)

The sequence of pipeline execution is outlined below. For a detailed breakdown of the execution order within each individual pipeline step (denoted as pipeline_definition in the diagram), please consult the Pipeline steps section.

resolver_definitionauthorizationpre_scriptloop_withpipeline_definitionpost_validationpipeline_stepspost_script

The sequence of pipeline execution is outlined below. For a detailed breakdown of the execution order within each individual pipeline step (denoted as PipelineDefinition in the diagram), please consult the Pipeline steps section.

ResolverDefinitionauthorizationpreScriptforEachPipelineDefinitionpostValidationPipelineStepspostScript

Pipeline steps

The steps array contains the implementations of the pipeline steps.

Properties

PropertyTypeRequiredDescription
namestringYesThe step's name
operationobjectYesThe GraphQL query the step will run
descriptionstringNoThe description of what this step does
context_dataobjectNoUser settable data in JSON that can be referenced in pre_script and post_script blocks
loop_withstringNoThe CEL expression to evaluate for looping this step
run_ifstringNoThe CEL expression to evaluate for running this step
skip_on_operation_errorbooleanNoWhether to skip this step if the operation fails

Scripting Properties

PropertyTypeScripting LanguageDescription
pre_validationstringCELA script block to validate the data before the pre_script execution and throw an error if it is invalid
pre_scriptstringCELA script block to transform the data that will be passed to the GraphQL query
pre_hookstringJavaScriptA JavaScript block that validates and transforms the data to be passed to the GraphQL query
post_scriptstringCELA script block where the result of the GraphQL query can be transformed
post_validationstringCELA script block to validate the data after the post_script execution and throw an error if it is invalid
post_hookstringJavaScriptA JavaScript block where the result of the GraphQL query can be validated and transformed

For comprehensive information on the properties of a pipeline step, check the Tailor Platform Provider documentation.

Example

<span><span style="color: var(--shiki-token-function)">steps</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">name</span><span style="color: var(--shiki-color-text)">     </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;createUserInfo&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">pre_script</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  ({</span></span>
<span><span style="color: var(--shiki-token-string)">    &quot;name&quot;: context.args.input.name,</span></span>
<span><span style="color: var(--shiki-token-string)">    &quot;email&quot;: context.args.input.email</span></span>
<span><span style="color: var(--shiki-token-string)">  })</span></span>
<span><span style="color: var(--shiki-token-string)">  EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  operation = {</span></span>
<span><span style="color: var(--shiki-token-string)">    tailor_graphql = {</span></span>
<span><span style="color: var(--shiki-token-string)">      invoker = {</span></span>
<span><span style="color: var(--shiki-token-string)">        event_user = true</span></span>
<span><span style="color: var(--shiki-token-string)">      }</span></span>
<span><span style="color: var(--shiki-token-string)">      query = &lt;&lt;EOF</span></span>
<span><span style="color: var(--shiki-token-string)">        mutation($name: String!, $email: String!) {</span></span>
<span><span style="color: var(--shiki-token-string)">        createUser(input: {</span></span>
<span><span style="color: var(--shiki-token-string)">          name: $name,</span></span>
<span><span style="color: var(--shiki-token-string)">          email: $email</span></span>
<span><span style="color: var(--shiki-token-string)">        }) {</span></span>
<span><span style="color: var(--shiki-token-string)">             id</span></span>
<span><span style="color: var(--shiki-token-string)">             name</span></span>
<span><span style="color: var(--shiki-token-string)">          }</span></span>
<span><span style="color: var(--shiki-token-string)">        }</span></span>
<span><span style="color: var(--shiki-token-string)">      EOF</span></span>
<span><span style="color: var(--shiki-token-string)">    }</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-token-string)">  post_script = &lt;&lt;EOF</span></span>
<span><span style="color: var(--shiki-token-string)">    args.createUser</span></span>
<span><span style="color: var(--shiki-token-string)">  EOF</span></span>
<span><span style="color: var(--shiki-token-string)">}]</span></span>
<span></span>

The Pipelines array contains the implementations of the steps.

Properties

PropertyTypeRequiredDescription
NamestringNoThe step's name
DescriptionstringYesThe description of what this step does
InvokerobjectNoThe user role may be required to execute the query, depending on the type of query
ContextDataobjectNoUser settable data in JSON that can be referenced in PreScript and PostScript blocks
TeststringNoA script block to test if the step should be executed or not. If the test fails, the step will be skipped but the pipeline execution continues to the next step
OperationobjectYesThe GraphQL query the step will run
ForEacharrayNoAn array object that will be iterated over. When using ForEach, each property holds the current item being evaluated in the iteration. This item is accessible in Test, PreScript, PreValidation, Operation, PostScript, and PostValidation. See the data manipulation section for each.

Scripting Properties

PropertyTypeScripting LanguageDescription
PreValidationstringCELA script block to validate the data before the PreScript execution and throw an error if it is invalid
PreScriptstringCELA script block to transform the data that will be passed to the GraphQL query
PreHookstringJavaScriptA JavaScript block that validates and transforms the data to be passed to the GraphQL query
PostScriptstringCELA script block where the result of the GraphQL query can be transformed
PostValidationstringCELA script block to validate the data after the PostScript execution and throw an error if it is invalid
PostHookstringJavaScriptA JavaScript block where the result of the GraphQL query can be validated and transformed

Example

<span><span style="color: var(--shiki-color-text)">Pipelines: [</span></span>
<span><span style="color: var(--shiki-color-text)">  {</span></span>
<span><span style="color: var(--shiki-color-text)">    Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">createsUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    Description: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">Creates a user</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">          createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">            id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">          }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">    PostScript: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">args.createUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    PostValidation: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      !args.createUser.id ? &quot;Failed at Create user step&quot; : &quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">]</span></span>
<span></span>

Execution Order (within a step)

The diagram below provides a detailed illustration of the execution sequence within each pipeline step (denoted as pipeline_definition.) Each of these steps is a subset of the overall resolver sequence. For a comprehensive understanding of the execution order at the resolver level, please refer to the Resolver section.

pipeline_definitionpre_validationpre_scriptgraphQL_operationgraphql_querypost_scriptpost_validationtruerun_iffalsestart of a pipeline stepnext pipeline step

The diagram below provides a detailed illustration of the execution sequence within each pipeline step (denoted as PipelineDefinition.) Each of these steps is a subset of the overall resolver sequence. For a comprehensive understanding of the execution order at the resolver level, please refer to the Resolver section.

PipelineDefinitionpreValidationpreScriptGraphQLOperationgraphqlQuerypostScriptpostValidationtruetestfalsestart of a pipeline stepnext pipeline step

Data manipulation

args

args is a placeholder variable that holds data for every pipeline. In the pre_script and post_script blocks, you can directly access input and output data using args, respectively.

Initially, args is populated with the arguments passed to the pipeline.

For instance, given the mutation bindUserToContract(userID: ID, contractID: ID), upon invocation the args object would look like:

<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">userID:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&lt;- value of the user ID argument -&gt;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">contractID:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;&lt;- value of the contract ID argument -&gt;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

with its values accessible in a pre_script block:

<span><span style="color: var(--shiki-token-function)">pre_script</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  {</span></span>
<span><span style="color: var(--shiki-token-string)">    uid: args.userID,</span></span>
<span><span style="color: var(--shiki-token-string)">    cid: args.contractID</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span></span>

The next step in the chain will receive as args the value resulting from the query execution or the value from the postScript block, if specified:

<span><span style="color: var(--shiki-token-function)">operation</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">tailor_graphql</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">invoker</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-function)">event_user</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">query</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">      mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string)">        createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string)">          id</span></span>
<span><span style="color: var(--shiki-token-string)">        }</span></span>
<span><span style="color: var(--shiki-token-string)">      }</span></span>
<span><span style="color: var(--shiki-token-string)">    EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-token-string)">}</span></span>
<span><span style="color: var(--shiki-token-string)">// the next step will receive </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-function)">args</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-string)"> as the following object:</span></span>
<span><span style="color: var(--shiki-token-string)">// { createUser: { id: &quot;&lt;- newly created user ID -&gt;&quot; } }</span></span>
<span></span>
<span><span style="color: var(--shiki-token-function)">operation</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">tailor_graphql</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">invoker</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">{</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-function)">event_user</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">query</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">      mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string)">        createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string)">          id</span></span>
<span><span style="color: var(--shiki-token-string)">        }</span></span>
<span><span style="color: var(--shiki-token-string)">      }</span></span>
<span><span style="color: var(--shiki-token-string)">    EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-token-string)">}</span></span>
<span><span style="color: var(--shiki-token-string)">post_script = &quot;args.createUser&quot;</span></span>
<span><span style="color: var(--shiki-token-string)">// the next step will receive </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-function)">args</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-string)"> as the following object:</span></span>
<span><span style="color: var(--shiki-token-string)">// { id: &quot;&lt;- newly created user ID -&gt;&quot; }</span></span>
<span></span>

args is a placeholder variable that holds data for every pipeline. In the PreScript and PostScript blocks, you can directly access input and output data using args, respectively.

Initially, args is populated with the arguments passed to the pipeline.

For instance, given the mutation bindUserToContract(userID: ID, contractID: ID), upon invocation the args object would look like:

<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  userID: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">&lt;- value of the user ID argument -&gt;</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  contractID: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">&lt;- value of the contract ID argument -&gt;</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

with its values accessible in a PreScript block:

<span><span style="color: var(--shiki-color-text)">PreScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    uid: args.userID,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    cid: args.contractID</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span></span>

The next step in the chain will receive as args the value resulting from the query execution or the value from the postScript block, if specified:

<span><span style="color: var(--shiki-color-text)">Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// the next step will receive `args` as the following object:</span></span>
<span><span style="color: var(--shiki-token-comment)">// { createUser: { id: &quot;&lt;- newly created user ID -&gt;&quot; } }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span><span style="color: var(--shiki-color-text)">PostScript: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">args.createUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// the next step will receive `args` as the following object:</span></span>
<span><span style="color: var(--shiki-token-comment)">// { id: &quot;&lt;- newly created user ID -&gt;&quot; }</span></span>
<span></span>

context

While args allows you to manipulate the input and output data that precedes the current step directly, using context you can reference the result data from any step that preceded in the chain.

To do so, you need to reference the name of the step within the context object:

<span><span style="color: var(--shiki-color-text)">steps = [</span></span>
<span><span style="color: var(--shiki-color-text)">  {</span></span>
<span><span style="color: var(--shiki-color-text)">    name     = </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">createUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    operation = {</span></span>
<span><span style="color: var(--shiki-color-text)">      tailor_graphql = {</span></span>
<span><span style="color: var(--shiki-color-text)">        invoker = {</span></span>
<span><span style="color: var(--shiki-color-text)">          event_user = </span><span style="color: var(--shiki-token-constant)">true</span></span>
<span><span style="color: var(--shiki-color-text)">        }</span></span>
<span><span style="color: var(--shiki-color-text)">        query = </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-color-text)">          mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-color-text)">            createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-color-text)">              id</span></span>
<span><span style="color: var(--shiki-color-text)">            } </span></span>
<span><span style="color: var(--shiki-color-text)">          }</span></span>
<span><span style="color: var(--shiki-color-text)">        EOF</span></span>
<span><span style="color: var(--shiki-color-text)">      }</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">    post_script = </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">args.createUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span></span>
<span><span style="color: var(--shiki-color-text)">  {</span></span>
<span><span style="color: var(--shiki-color-text)">    name = </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">performsSomething</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  {</span></span>
<span><span style="color: var(--shiki-color-text)">    name = </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">performsYetAnotherThing</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// pulling the ID of the user that was created in the `createsUser` step</span></span>
<span><span style="color: var(--shiki-color-text)">    pre_script = </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-color-text)">      {</span></span>
<span><span style="color: var(--shiki-color-text)">        userID: context.pipeline.createsUser.id</span></span>
<span><span style="color: var(--shiki-color-text)">      }</span></span>
<span><span style="color: var(--shiki-color-text)">    EOF</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">]</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">createsUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    Query: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      mutation($input: CreateUserInput!) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        createUser(input: $input) {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">          id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">        }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">  PostScript: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">args.createUser</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">performsSomething</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">}</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">performsYetAnotherThing</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// pulling the ID of the user that was created in the `createsUser` step</span></span>
<span><span style="color: var(--shiki-color-text)">  PreScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      userID: context.pipeline.createsUser.id</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

context_data

With context_data you can make any serializable data available to your pipelines.

If for instance you have a shared object across your application, you can make it accessible by doing something like:

<span><span style="color: var(--shiki-token-function)">context_data</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">json.Marshal</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-function)">settings.shared</span><span style="color: var(--shiki-color-text)">)</span></span>
<span><span style="color: var(--shiki-token-function)">pre_script</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">&lt;&lt;</span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span><span style="color: var(--shiki-token-string)">  {</span></span>
<span><span style="color: var(--shiki-token-string)">    &quot;key&quot;: context.data.shared.value,</span></span>
<span><span style="color: var(--shiki-token-string)">    // ...</span></span>
<span><span style="color: var(--shiki-token-string)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">EOF</span></span>
<span></span>

With contextData you can make any serializable data available to your pipelines.

If for instance you have a shared object across your application, you can make it accessible by doing something like:

<span><span style="color: var(--shiki-color-text)">contextData: </span><span style="color: var(--shiki-token-constant)">json</span><span style="color: var(--shiki-token-function)">.Marshal(settings.shared)</span></span>
<span><span style="color: var(--shiki-color-text)">PreScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    &quot;key&quot;: context.data.shared.value,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    // ...</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span></span>

Inside the loop

When using loop_with, each holds the current item being evaluated in the iteration. This item is accessible in run_if, pre_script, pre_validation, operation, post_script, and post_validation.

<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">name</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;performsSomething&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">//</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">Assume</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">a</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">list</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">of</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">products</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">is</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">passed</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">the</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">previous</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string)">step</span><span style="color: var(--shiki-token-string-expression)">&#39;s post_script</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  loop_with = &quot;args.products&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  pre_script = &lt;&lt;EOF</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      id: each.id,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      name: each.name</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  EOF</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  // args.products[0].id equals to &quot;id&quot; in the first iteration</span></span>
<span><span style="color: var(--shiki-token-string-expression)">}</span></span>
<span></span>

When using ForEach, each holds the current item being evaluated in the iteration. This item is accessible in Test, PreScript, PreValidation, Operation, PostScript, and PostValidation.

<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  Name: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">performsSomething</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Assume a list of products is passed from the previous step&#39;s PostScript</span></span>
<span><span style="color: var(--shiki-color-text)">  ForEach: </span><span style="color: var(--shiki-color-text)">&quot;</span><span style="color: var(--shiki-token-string-expression)">args.products</span><span style="color: var(--shiki-color-text)">&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  PreScript: </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    {</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      id: each.id,</span></span>
<span><span style="color: var(--shiki-token-string-expression)">      name: each.name</span></span>
<span><span style="color: var(--shiki-token-string-expression)">    }</span></span>
<span><span style="color: var(--shiki-token-string-expression)">  </span><span style="color: var(--shiki-color-text)">&quot;&quot;&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// args.products[0].id equals to &quot;id&quot; in the first iteration</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

CEL scripting

CEL script can be used to perform data transformations between steps. For more details, see the reference.