- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
3.6.3. Workflow Constraints
This chapter lists constraints of defining a workflow or its steps.
Workflow Constraints#
No Async Functions#
The function passed to createWorkflow
can’t be an async function:
No Direct Variable Manipulation#
You can’t directly manipulate variables within the workflow's constructor function.
Instead, use transform
from the Workflows SDK:
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 const str1 = step1(input)6 const str2 = step2(input)7 8 return new WorkflowResponse({9 message: `${str1}${str2}`,10 })11})12 13// Do14const myWorkflow = createWorkflow(15 "hello-world", 16 function (input: WorkflowInput) {17 const str1 = step1(input)18 const str2 = step2(input)19 20 const result = transform(21 {22 str1,23 str2,24 },25 (input) => ({26 message: `${input.str1}${input.str2}`,27 })28 )29 30 return new WorkflowResponse(result)31})
Create Dates in transform#
When you use new Date()
in a workflow's constructor function, the date is evaluated when Medusa creates the internal representation of the workflow, not during execution.
Instead, create the date using transform
.
For example:
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 const today = new Date()6 7 return new WorkflowResponse({8 today,9 })10})11 12// Do13const myWorkflow = createWorkflow(14 "hello-world", 15 function (input: WorkflowInput) {16 const today = transform({}, () => new Date())17 18 return new WorkflowResponse({19 today,20 })21})
No If Conditions#
You can't use if-conditions in a workflow.
Instead, use when-then from the Workflows SDK:
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 if (input.is_active) {6 // perform an action7 }8})9 10// Do (explained in the next chapter)11const myWorkflow = createWorkflow(12 "hello-world", 13 function (input: WorkflowInput) {14 when(input, (input) => {15 return input.is_active16 })17 .then(() => {18 // perform an action19 })20})
You can also pair multiple when-then
blocks to implement an if-else
condition as explained in this chapter.
No Conditional Operators#
You can't use conditional operators in a workflow, such as ??
or ||
.
Instead, use transform
to store the desired value in a variable.
Logical Or (||) Alternative#
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 const message = input.message || "Hello"6})7 8// Do9// other imports...10import { transform } from "@medusajs/framework/workflows-sdk"11 12const myWorkflow = createWorkflow(13 "hello-world", 14 function (input: WorkflowInput) {15 const message = transform(16 {17 input,18 },19 (data) => data.input.message || "hello"20 )21})
Nullish Coalescing (??) Alternative#
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 const message = input.message ?? "Hello"6})7 8// Do9// other imports...10import { transform } from "@medusajs/framework/workflows-sdk"11 12const myWorkflow = createWorkflow(13 "hello-world", 14 function (input: WorkflowInput) {15 const message = transform(16 {17 input,18 },19 (data) => data.input.message ?? "hello"20 )21})
Double Not (!!) Alternative#
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 step1({6 isActive: !!input.is_active,7 })8})9 10// Do11// other imports...12import { transform } from "@medusajs/framework/workflows-sdk"13 14const myWorkflow = createWorkflow(15 "hello-world", 16 function (input: WorkflowInput) {17 const isActive = transform(18 {19 input,20 },21 (data) => !!data.input.is_active22 )23 24 step1({25 isActive,26 })27})
Ternary Alternative#
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 step1({6 message: input.is_active ? "active" : "inactive",7 })8})9 10// Do11// other imports...12import { transform } from "@medusajs/framework/workflows-sdk"13 14const myWorkflow = createWorkflow(15 "hello-world", 16 function (input: WorkflowInput) {17 const message = transform(18 {19 input,20 },21 (data) => {22 return data.input.is_active ? "active" : "inactive"23 }24 )25 26 step1({27 message,28 })29})
Optional Chaining (?.) Alternative#
1// Don't2const myWorkflow = createWorkflow(3 "hello-world", 4 function (input: WorkflowInput) {5 step1({6 name: input.customer?.name,7 })8})9 10// Do11// other imports...12import { transform } from "@medusajs/framework/workflows-sdk"13 14const myWorkflow = createWorkflow(15 "hello-world", 16 function (input: WorkflowInput) {17 const name = transform(18 {19 input,20 },21 (data) => data.input.customer?.name22 )23 24 step1({25 name,26 })27})
Step Constraints#
Returned Values#
A step must only return serializable values, such as primitive values or an object.
Values of other types, such as Maps, aren't allowed.
1// Don't2import { 3 createStep,4 StepResponse,5} from "@medusajs/framework/workflows-sdk"6 7const step1 = createStep(8 "step-1",9 (input, { container }) => {10 const myMap = new Map()11 12 // ...13 14 return new StepResponse({15 myMap,16 })17 }18)19 20// Do21import { 22 createStep,23 StepResponse,24} from "@medusajs/framework/workflows-sdk"25 26const step1 = createStep(27 "step-1",28 (input, { container }) => {29 const myObj: Record<string, unknown> = {}30 31 // ...32 33 return new StepResponse({34 myObj,35 })36 }37)