4.4.2. Brand Example: Handle Event to Sync Third-Party System

Example ChapterThis chapter covers how to emit an event when a brand is created, listen to that event in a subscriber, and create the brand in the third-party system as a step of the "Integrate Systems" chapter .

1. Emit Custom Event for Brand Creation#

To handle brand-creation event, you'll emit a custom event when a brand is created.

In the createBrandWorkflow defined in src/workflows/create-brand/index.ts, use the emitEventStep helper step imported from @medusajs/medusa/core-flows after the createBrandStep:

src/workflows/create-brand/index.ts
1// other imports...2import { 3  emitEventStep,4} from "@medusajs/medusa/core-flows"5
6// ...7
8export const createBrandWorkflow = createWorkflow(9  "create-brand",10  (input: CreateBrandInput) => {11    // ...12
13    emitEventStep({14      eventName: "brand.created",15      data: {16        id: brand.id,17      },18    })19
20    return new WorkflowResponse(brand)21  }22)

The emitEventStep accepts as a parameter an object having two properties:

  • eventName: The name of the event to emit.
  • data: The data payload to emit with the event. This is useful for subscribers to access the created brand.

2. Create Sync to Third-Party System Workflow#

Next, you'll create the workflow that syncs the created brand to the third-party system.

Create the file src/workflows/sync-brand-to-system/index.ts with the following content:

src/workflows/sync-brand-to-system/index.ts
1import {2  createWorkflow,3  WorkflowResponse,4} from "@medusajs/framework/workflows-sdk"5
6export type SyncBrandToSystemInput = {7  id: string8}9
10export const syncBrandToSystemWorkflow = createWorkflow(11  "sync-brand-to-system",12  (input: SyncBrandToSystemInput) => {13    // ...14  }15)

This defines an empty workflow and its expected input.

Create createBrandInSystemStep#

Next, create the step that syncs the brand in the file src/workflows/sync-brand-to-system/steps/create-brand-in-system.ts:

src/workflows/sync-brand-to-system/steps/create-brand-in-system.ts
7import { BRAND_MODULE } from "../../../modules/brand"8
9export const createBrandInSystemStep = createStep(10  "create-brand-in-system",11  async ({ id }: SyncBrandToSystemInput, { container }) => {12    const brandModuleService: BrandModuleService = container.resolve(13      BRAND_MODULE14    )15
16    const brand = await brandModuleService.retrieveBrand(id)17  18    await brandModuleService.client.createBrand(brand)19
20    return new StepResponse(null, brand.id)21  },22  async (id, { container }) => {23    const brandModuleService: BrandModuleService = container.resolve(24      BRAND_MODULE25    )26
27    await brandModuleService.client.deleteBrand(id)28  }29)

This step resolves the Brand Module's main service and uses its client property to access its internal service that integrates the third-party system.

In the step, you use the createBrand method of the client to create the brand in the third-party system.

In the compensation function, you undo the step's action using the deleteBrand method of the client.

Add Step to Workflow#

Finally, add this step to the syncBrandToSystemWorkflow in src/workflows/sync-brand-to-system/index.ts:

src/workflows/sync-brand-to-system/index.ts
1// other imports...2import { createBrandInSystemStep } from "./steps/create-brand-in-system"3
4// ...5
6export const syncBrandToSystemWorkflow = createWorkflow(7  "sync-brand-to-system",8  (input: SyncBrandToSystemInput) => {9    createBrandInSystemStep(input)10
11    return new WorkflowResponse(undefined)12  }13)

The workflow now calls the step and returns an undefined result.


3. Handle brand.created Event#

To handle the brand.created event, create a subscriber at src/subscribers/brand-created.ts with the following content:

src/subscribers/brand-created.ts
1import type {2  SubscriberConfig,3  SubscriberArgs,4} from "@medusajs/framework"5import { syncBrandToSystemWorkflow } from "../workflows/sync-brand-to-system"6
7export default async function brandCreatedHandler({8  event: { data },9  container,10}: SubscriberArgs<{ id: string }>) {11  await syncBrandToSystemWorkflow(container).run({12    input: data,13  })14}15
16export const config: SubscriberConfig = {17  event: "brand.created",18}

The subscriber handler accesses the event payload in the event.data property of its object parameter.

NoteLearn more about subscribers in this guide .

It then executes the syncBrandToSystemWorkflow, passing it the ID of the brand to create in the third-party system.


Test it Out#

To test it out, start the Medusa application and create a brand using the API route created in a previous chapter.

If you check the logs, you'll find the brand.created event was emitted, and that the request to the third-party system was simulated.


Next Chapter: Sync Brand from Third-Party System to Medusa#

In the next chapter, you'll learn how to sync brands in the third-party system into Medusa using a workflow and a scheduled job.

Was this chapter helpful?
Edit this page