docs: add routing page (#9550)
- Add a new homepage to `book` project for the routing page - Move all main doc pages to be under `/v2/learn` (and added redirects + fixed links across docs) - Other: add admin components to resources dropdown + fixes to search on mobile. Closes DX-955 Preview: https://docs-v2-git-docs-router-page-medusajs.vercel.app/v2
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
import { Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Brand Example: Handle Event to Sync Third-Party System`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
<Note title="Example Chapter">
|
||||
|
||||
This 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](../page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
## 1. Emit Custom Event for Brand Creation
|
||||
|
||||
<Prerequisites
|
||||
items={[
|
||||
{
|
||||
text: "Brand Module with createBrandWorkflow",
|
||||
link: "/customization/custom-features/workflow"
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
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`:
|
||||
|
||||
export const eventHighlights = [
|
||||
["13", "emitEventStep", "Emit an event."],
|
||||
["14", "eventName", "The event's name."],
|
||||
["15", "data", "The data to pass in the payload."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/create-brand/index.ts" highlights={eventHighlights}
|
||||
// other imports...
|
||||
import {
|
||||
emitEventStep,
|
||||
} from "@medusajs/medusa/core-flows"
|
||||
|
||||
// ...
|
||||
|
||||
export const createBrandWorkflow = createWorkflow(
|
||||
"create-brand",
|
||||
(input: CreateBrandInput) => {
|
||||
// ...
|
||||
|
||||
emitEventStep({
|
||||
eventName: "brand.created",
|
||||
data: {
|
||||
id: brand.id,
|
||||
},
|
||||
})
|
||||
|
||||
return new WorkflowResponse(brand)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```ts title="src/workflows/sync-brand-to-system/index.ts"
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
export type SyncBrandToSystemInput = {
|
||||
id: string
|
||||
}
|
||||
|
||||
export const syncBrandToSystemWorkflow = createWorkflow(
|
||||
"sync-brand-to-system",
|
||||
(input: SyncBrandToSystemInput) => {
|
||||
// ...
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
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`:
|
||||
|
||||
export const stepHighlights = [
|
||||
["18", "createBrand", "Create a brand in the third-party system."],
|
||||
["27", "deleteBrand", "Delete the brand in the third-party system if an error occurs."]
|
||||
]
|
||||
|
||||
```ts title="src/workflows/sync-brand-to-system/steps/create-brand-in-system.ts" highlights={stepHighlights} collapsibleLines="1-8" expandButtonLabel="Show Imports"
|
||||
import {
|
||||
createStep,
|
||||
StepResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { SyncBrandToSystemInput } from ".."
|
||||
import BrandModuleService from "../../../modules/brand/service"
|
||||
import { BRAND_MODULE } from "../../../modules/brand"
|
||||
|
||||
export const createBrandInSystemStep = createStep(
|
||||
"create-brand-in-system",
|
||||
async ({ id }: SyncBrandToSystemInput, { container }) => {
|
||||
const brandModuleService: BrandModuleService = container.resolve(
|
||||
BRAND_MODULE
|
||||
)
|
||||
|
||||
const brand = await brandModuleService.retrieveBrand(id)
|
||||
|
||||
await brandModuleService.client.createBrand(brand)
|
||||
|
||||
return new StepResponse(null, brand.id)
|
||||
},
|
||||
async (id, { container }) => {
|
||||
const brandModuleService: BrandModuleService = container.resolve(
|
||||
BRAND_MODULE
|
||||
)
|
||||
|
||||
await brandModuleService.client.deleteBrand(id)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
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 the step to the `syncBrandToSystemWorkflow` in `src/workflows/sync-brand-to-system/index.ts`:
|
||||
|
||||
```ts title="src/workflows/sync-brand-to-system/index.ts"
|
||||
// other imports...
|
||||
import { createBrandInSystemStep } from "./steps/create-brand-in-system"
|
||||
|
||||
// ...
|
||||
|
||||
export const syncBrandToSystemWorkflow = createWorkflow(
|
||||
"sync-brand-to-system",
|
||||
(input: SyncBrandToSystemInput) => {
|
||||
createBrandInSystemStep(input)
|
||||
|
||||
return new WorkflowResponse(undefined)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```ts title="src/subscribers/brand-created.ts"
|
||||
import type {
|
||||
SubscriberConfig,
|
||||
SubscriberArgs,
|
||||
} from "@medusajs/framework"
|
||||
import { syncBrandToSystemWorkflow } from "../workflows/sync-brand-to-system"
|
||||
|
||||
export default async function brandCreatedHandler({
|
||||
event: { data },
|
||||
container,
|
||||
}: SubscriberArgs<{ id: string }>) {
|
||||
await syncBrandToSystemWorkflow(container).run({
|
||||
input: data,
|
||||
})
|
||||
}
|
||||
|
||||
export const config: SubscriberConfig = {
|
||||
event: "brand.created",
|
||||
}
|
||||
```
|
||||
|
||||
The subscriber handler accesses the event payload in the `event.data` property of its object parameter.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about subscribers [in this guide](../../../basics/events-and-subscribers/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
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](../../custom-features/api-route/page.mdx#test-api-route).
|
||||
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user