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
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
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)">"</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)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">tailor.build/{APPLICATION_NAME}/environment</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)">"</span><span style="color: var(--shiki-token-string-expression)">tailor.build/{APPLICATION_NAME}/services/pipeline/resolvers</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)">pipeline.#Spec </span><span style="color: var(--shiki-token-keyword)">&</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)">"</span><span style="color: var(--shiki-token-string-expression)">my-pipeline</span><span style="color: var(--shiki-color-text)">"</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>
Manifest
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)">&</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)">"</span><span style="color: var(--shiki-token-string-expression)">my-pipeline</span><span style="color: var(--shiki-color-text)">"</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, onlyMutation
andQuery
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 Resolver
object features the implementations of the pipelines.
Properties
Name
: The pipeline object name (required).Description
: The description of the pipeline (required).Inputs
: The input types of the pipeline. See the following section.Response
: The response type of the pipeline. See the following section.Authorization
: The authorization rules for the pipeline (required). If you don't have a specific authorization rule, set pipeline.#AuthInsecure.OperationType
: The operation type is eitherquery
ormutation
. If no value is specified, it defaults tomutation
if the operation in the pipelines is a mutation; otherwise, it defaults toquery
.PreScript
: A script block where the input that will be passed to the pipeline can be transformed.PreHook
: A script block where the input that will be passed to the pipeline can be validated and transformed using Javascript.Pipelines
: A list that contains pipeline steps.PostScript
: A 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.
- 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
PostHook
: A script block where the result of the pipeline can be validated and transformed using Javascript.PublishExecutionEvents
: A boolean field that must be set totrue
to enable the publishing of pipeline execution events to the executor service.
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 ofField
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)">&</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)">"</span><span style="color: var(--shiki-token-string-expression)">EmployeeType</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> Values: [</span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">MANAGER</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 style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">STAFF</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">your_defined_input_type</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">userID</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">User ID</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">code</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">Contract code</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">bindDate</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">bindTime</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">bindDateTime</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">roleType</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">Employee type</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">your_defined_response_type</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">userID</span><span style="color: var(--shiki-color-text)">"</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)">&</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)">"</span><span style="color: var(--shiki-token-string-expression)">bindUserToContract</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> Description: </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">Bind a User to a Contract</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">input</span><span style="color: var(--shiki-color-text)">"</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)">"</span><span style="color: var(--shiki-token-string-expression)">mutation</span><span style="color: var(--shiki-color-text)">"</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)">""</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)">""</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 PipelineDefinition in the diagram), please consult the Pipeline steps section.
Pipeline steps
The Pipelines
array contains the implementations of the steps.
Properties
Name
: The step's name.Description
: The description of what this step does (required).Invoker
: The user role may be required to execute the query, depending on the type of query.ContextData
: User settable data in JSON that can be referenced inPreScript
andPostScript
blocks.Test
: A 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.PreValidation
: A script block to validate the data before thePreScript
execution and throw an error if it is invalid.PreScript
: A script block to transform the data that will be passed to the GraphQL query.PreHook
: A JavaScript block that validates and transforms the data to be passed to the GraphQL query.Operation
: The GraphQL query the step will run.PostScript
: A script block where the result of the GraphQL query can be transformed.PostValidation
: A script block to validate the data after thePostScript
execution and throw an error if it is invalid.PostHook
: A JavaScript block where the result of the GraphQL query can be validated and transformed.ForEach
: An 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 inTest
,PreScript
,PreValidation
,Operation
,PostScript
, andPostValidation
. See the data manipulation section foreach
.
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)">"</span><span style="color: var(--shiki-token-string-expression)">createsUser</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> Description: </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">Creates a user</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&</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)">"""</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)">"""</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)">"</span><span style="color: var(--shiki-token-string-expression)">args.createUser</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> PostValidation: </span><span style="color: var(--shiki-color-text)">"""</span></span>
<span><span style="color: var(--shiki-token-string-expression)"> !args.createUser.id ? "Failed at Create user step" : ""</span></span>
<span><span style="color: var(--shiki-token-string-expression)"> </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>
<span></span>
Execution Order (within a 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.
Data manipulation
args
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)">"</span><span style="color: var(--shiki-token-string-expression)"><- value of the user ID argument -></span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> contractID: </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)"><- value of the contract ID argument -></span><span style="color: var(--shiki-color-text)">"</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)">"""</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)">"""</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)">&</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)">"""</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)">"""</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 as `args` the following object:</span></span>
<span><span style="color: var(--shiki-token-comment)">// { createUser: { id: "<- newly created user ID ->" } }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&</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)">"""</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)">"""</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)">"</span><span style="color: var(--shiki-token-string-expression)">args.createUser</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 as `args` the following object:</span></span>
<span><span style="color: var(--shiki-token-comment)">// { id: "<- newly created user ID ->" }</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)">{</span></span>
<span><span style="color: var(--shiki-color-text)"> Name: </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">createsUser</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> Operation: pipeline.#GraphqlOperation </span><span style="color: var(--shiki-token-keyword)">&</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)">"""</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)">"""</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)">"</span><span style="color: var(--shiki-token-string-expression)">args.createUser</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-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)">"</span><span style="color: var(--shiki-token-string-expression)">performsSomething</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-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)">"</span><span style="color: var(--shiki-token-string-expression)">performsYetAnotherThing</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-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)">"""</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)">"""</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.args
holds the resolver's arguments, while args
contains data for each individual pipeline. Use context
to access data throughout the entire pipeline chain."
ContextData
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)">"""</span></span>
<span><span style="color: var(--shiki-token-string-expression)"> {</span></span>
<span><span style="color: var(--shiki-token-string-expression)"> "key": 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)">"""</span></span>
<span></span>
each
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)">"</span><span style="color: var(--shiki-token-string-expression)">performsSomething</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-comment)">// Assume a list of products is passed from the previous step's PostScript</span></span>
<span><span style="color: var(--shiki-color-text)"> ForEach: </span><span style="color: var(--shiki-color-text)">"</span><span style="color: var(--shiki-token-string-expression)">args.products</span><span style="color: var(--shiki-color-text)">"</span></span>
<span><span style="color: var(--shiki-color-text)"> PreScript: </span><span style="color: var(--shiki-color-text)">"""</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)">"""</span></span>
<span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-comment)">// args.products[0].id equals to "id" 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.