2.10. Workflows

In this chapter, you’ll learn about workflows and how to define and execute them.

What is a Workflow?#

A workflow is a series of queries and actions that complete a task.

You construct a workflow similar to how you create a JavaScript function, but unlike regular functions, a workflow creates an internal representation of your steps.

By using a workflow, you can track its execution's progress, provide roll-back logic for each step to mitigate data inconsistency when errors occur, automatically retry failing steps, and do much more, as explained in later chapters.


How to Create and Execute a Workflow?#

1. Create the Steps#

A workflow is made of a series of steps. A step is created using the createStep utility function imported from @medusajs/framework/workflows-sdk.

Create the file src/workflows/hello-world.ts with the following content:

src/workflows/hello-world.ts
1import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"2
3const step1 = createStep("step-1", async () => {4  return new StepResponse(`Hello from step one!`)5})

This creates one step that returns a hello message.

Steps can accept input parameters.

For example, add the following to src/workflows/hello-world.ts:

src/workflows/hello-world.ts
1type WorkflowInput = {2  name: string3}4
5const step2 = createStep("step-2", async ({ name }: WorkflowInput) => {6  return new StepResponse(`Hello ${name} from step two!`)7})

2. Create a Workflow#

Next, add the following to the same file to create the workflow using the createWorkflow function:

src/workflows/hello-world.ts
1import {2  // other imports...3  createWorkflow,4  WorkflowResponse,5} from "@medusajs/framework/workflows-sdk"6
7// ...8
9const myWorkflow = createWorkflow(10  "hello-world",11  function (input: WorkflowInput) {12    const str1 = step1()13    // to pass input14    const str2 = step2(input)15
16    return new WorkflowResponse({17      message: str1,18    })19  }20)21
22export default myWorkflow

This creates a hello-world workflow. When you create a workflow, it’s constructed but not executed yet.

The workflow must return an instance of WorkflowResponse, whose first parameter is returned to workflow executors.

3. Execute the Workflow#

You can execute a workflow from different resources within Medusa.

  • Use API routes to execute the workflow in response to an API request or a webhook.
  • Use subscribers to execute a workflow when an event is triggered.
  • Use scheduled jobs to execute a workflow on a regular schedule.

To execute the workflow, invoke it passing the Medusa container as a parameter. Then, use its run method:

4. Test Workflow#

To test out your workflow, start your Medusa application:

Then, send a GET request to /workflow:

Code
curl http://localhost:9000/workflow?name=john

You’ll receive the following response:

Code
1{2  "message": "Hello from step one!"3}

When to Use Workflows#

Use workflows whenYou're implementing a custom feature exposed by an API route, or used in subscribers or scheduled jobs.

Resolve Resources#

Each step in the workflow receives as a second parameter a context object. The object holds a container property which is the Medusa container. Use it to resolve other resources, such as services, of your Medusa application.

For example:

src/workflows/product-count.ts
8import { Modules } from "@medusajs/framework/utils"9
10const step1 = createStep("step-1", async (_, context) => {11  const productModuleService: IProductModuleService =12    context.container.resolve(Modules.PRODUCT)13
14  const [, count] = await productModuleService.listAndCountProducts()15
16  return new StepResponse(count)17})18
19const myWorkflow = createWorkflow(20  "product-count",21  function () {22    const count = step1()23
24    return new WorkflowResponse({25      count,26    })27  }28)29
30export default myWorkflow

In step1, you resolve the Product Module's main service and use it to retrieve the product count.

Was this chapter helpful?
Edit this page