4.1.2. Define Workflow to Create a Brand

Example ChapterThis chapter covers how to define a workflow that creates a brand as part of the "Build Custom Features" chapter .

Workflows vs Services: Why use Workflows?#

When manipulating data, use workflows instead of invoking a service's methods directly in your API route or other customizations.

Workflows eliminate data inconsistency in your application with its compensation mechanism that undoes changes if an error occurs. For example, if a workflow's step creates a brand, it also defines a compensation mechanism to remove the brand if an error occurs.

NoteLearn more about workflows in this guide .

This is even more useful when you create workflows with many steps, or integrate third-party systems.


Create createBrandWorkflow#

Create the file src/workflows/create-brand/index.ts with the following content:

Code
1import {2  createWorkflow,3  WorkflowResponse,4} from "@medusajs/framework/workflows-sdk"5
6export type CreateBrandInput = {7  name: string8}9
10export const createBrandWorkflow = createWorkflow(11  "create-brand",12  (input: CreateBrandInput) => {13    // TODO14  }15)

For now, this workflow only defines its input. You'll create its step and use it in the workflow.


Create createBrandStep#

Create the file src/workflows/create-brand/steps/create-brand.ts with the following content:

src/workflows/create-brand/steps/create-brand.ts
7import BrandModuleService from "../../../modules/brand/service"8
9export const createBrandStep = createStep(10  "create-brand-step",11  async (input: CreateBrandInput, { container }) => {12    const brandModuleService: BrandModuleService = container.resolve(13      BRAND_MODULE14    )15
16    const brand = await brandModuleService.createBrands(input)17
18    return new StepResponse(brand, brand.id)19  }20)

This defines a createBrandStep. In the step, you resolve the Brand Module's main service and use its generated createBrands method, which accepts one or more objects of brands to create.

The step returns the created brand in the first parameter of the StepResponse's constructor.

Add Compensation Function to Step#

A compensation function rolls back changes made by the step if an error occurs in the workflow.

The second parameter of the StepResponse's constructor is passed to the compensation function.

To add the compensation function, pass a third parameter to createStep:

src/workflows/create-brand/steps/create-brand.ts
1export const createBrandStep = createStep(2  // ...3  async (id: string, { container }) => {4    const brandModuleService: BrandModuleService = container.resolve(5      BRAND_MODULE6    )7
8    await brandModuleService.deleteBrands(id)9  }10)

You resolve the Brand Module's main service and use its generated deleteBrands method to delete the brand created by the step.

TipThe deleteBrands method accepts an ID or an array of IDs of brands to delete.

So, when an error occurs during the workflow, the brand that was created by the step is deleted to maintain data consistency.


Add Step to Workflow#

Go back to the workflow at src/workflows/create-brand/index.ts and import the step you created:

Code
import { createBrandStep } from "./steps/create-brand"

Then, replace the TODO with the following:

Code
1const brand = createBrandStep(input)2
3return new WorkflowResponse(brand)

You use the createBrandStep to create the brand and return it in the workflow's response.


Next Step: Create Brand API Route#

In the next step, you'll create an API route that allows admin users to create a brand using this workflow.

Was this chapter helpful?
Edit this page