docs: add emit events + types documentation (#10026)

* docs: add emit events + types documentation

* vale fixes
This commit is contained in:
Shahed Nasser
2024-11-13 14:17:14 +02:00
committed by GitHub
parent 7a26e123bb
commit f151fb32aa
3 changed files with 155 additions and 9 deletions

View File

@@ -1,22 +1,50 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `${pageNumber} Emit an Event`,
title: `${pageNumber} Emit Workflow and Service Events`,
}
# {metadata.title}
In this chapter, you'll learn how to emit an event in a workflow.
In this chapter, you'll learn about event types and how to emit an event in a service or workflow.
## Emit Event Step
## Event Types
Medusa provides an `emitEventStep` helper step in the `@medusajs/medusa/core-flows` package that emits an event.
In your customization, you can emit an event, then listen to it in a subscriber and perform an asynchronus action, such as send a notification or data to a third-party system.
When you emit an event, you specify the event's name and data payload to pass with the event.
There are two types of events in Medusa:
1. Worflow event: an event that's emitted in a workflow after a commerce feature is performed. For example, Medusa emits the `order.placed` event after a cart is completed.
2. Service event: an event that's emitted to track, trace, or debug processes under the hood. For example, you can emit an event with an audit trail.
### Which Event Type to Use?
**Workflow events** are the most common event type in development, as most custom features and customizations are built around workflows.
Some examples of workflow events:
1. When a user creates a blog post and you're emitting an event to send a newsletter email.
2. When you finish syncing products to a third-party system and you want to notify the admin user of new products added.
3. When a customer purchases a digital product and you want to generate and send it to them.
You should only go for a **service event** if you're emitting an event for processes under the hood that don't directly affect front-facing features.
Some examples of service events:
1. When you're tracing data manipulation and changes, and you want to track every time some custom data is changed.
2. When you're syncing data with a search engine.
---
## Emit Event in a Workflow
To emit a workflow event, use the `emitEventStep` helper step provided in the `@medusajs/medusa/core-flows` package.
For example:
export const highlights = [
["13", "emitEventStep", "Emit an event."],
["14", `"custom.created"`, "The name of the event to emit."],
["14", `eventName`, "The name of the event to emit."],
["15", "data", "The data payload to pass with the event."]
]
@@ -37,12 +65,129 @@ const helloWorldWorkflow = createWorkflow(
eventName: "custom.created",
data: {
id: "123",
// other data payload
},
})
}
)
```
The `emitEventStep` accepts an object having the following properties:
- `eventName`: The event's name.
- `data`: The data payload as an object. You can pass any properties in the object, and subscribers listening to the event will receive this data in the event's payload.
In this example, you emit the event `custom.created` and pass in the data payload an ID property.
If you execute the workflow, the emit is emitted and any subscribers listening to the event are executed.
### Test it Out
If you execute the workflow, the event is emitted and you can see it in your application's logs.
Any subscribers listening to the event are executed.
---
## Emit Event in a Service
To emit a service event:
1. Resolve `event_bus` from the module's container in your service's constructor:
<CodeTabs group="service_type">
<CodeTab label="Extending Service Factory" value="service_factory">
```ts title="src/modules/hello/service.ts" highlights={["9"]}
import { IEventBusService } from "@medusajs/framework/types"
import { MedusaService } from "@medusajs/framework/utils"
class HelloModuleService extends MedusaService({
MyCustom,
}){
protected eventBusService_: AbstractEventBusModuleService
constructor({ event_bus }) {
super(...arguments)
this.eventBusService_ = event_bus
}
}
```
</CodeTab>
<CodeTab label="Without Service Factory" value="no_service_factory">
```ts title="src/modules/hello/service.ts" highlights={["6"]}
import { IEventBusService } from "@medusajs/framework/types"
class HelloModuleService {
protected eventBusService_: AbstractEventBusModuleService
constructor({ event_bus }) {
this.eventBusService_ = event_bus
}
}
```
</CodeTab>
</CodeTabs>
2. Use the event bus service's `emit` method in the service's methods to emit an event:
export const serviceHighlights = [
["6", "emit", "Emit an event."],
["7", "name", "The name of the event to emit."],
["8", "data", "The data payload to pass with the event."]
]
```ts title="src/modules/hello/service.ts" highlights={serviceHighlights}
class HelloModuleService {
// ...
performAction() {
// TODO perform action
this.eventBusService_.emit({
name: "custom.event",
data: {
id: "123",
// other data payload
}
})
}
}
```
The method accepts an object having the following properties:
- `name`: The event's name.
- `data`: The data payload as an object. You can pass any properties in the object, and subscribers listening to the event will receive this data in the event's payload.
3. By default, the Event Module's service isn't injected into your module's container. To add it to the container, pass it in the module's registration object in `medusa-config.ts` in the `dependencies` property:
export const depsHighlight = [
["8", "dependencies", "An array of module registration names to inject into the Module's container."],
]
```ts title="medusa-config.ts" highlights={depsHighlight}
import { Modules } from '@medusajs/framework/utils'
module.exports = defineConfig({
// ...
modules: [
{
resolve: "./src/modules/hello",
dependencies: [
Modules.EVENT_BUS
]
}
]
})
```
The `dependencies` property accepts an array of module registration keys. The specified modules' main services are injected into the module's container.
That's how you can resolve it in your module's main service's constructor.
### Test it Out
If you execute the `performAction` method of your service, the event is emitted and you can see it in your application's logs.
Any subscribers listening to the event are also executed.

View File

@@ -35,7 +35,7 @@ export const generatedEditDates = {
"app/learn/advanced-development/events-and-subscribers/data-payload/page.mdx": "2024-07-16T17:12:05+01:00",
"app/learn/advanced-development/data-models/default-properties/page.mdx": "2024-09-19T07:32:06.118Z",
"app/learn/advanced-development/workflows/advanced-example/page.mdx": "2024-09-11T10:46:59.975Z",
"app/learn/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-09-30T08:43:53.125Z",
"app/learn/advanced-development/events-and-subscribers/emit-event/page.mdx": "2024-11-11T15:17:58.045Z",
"app/learn/advanced-development/workflows/conditions/page.mdx": "2024-09-30T08:43:53.128Z",
"app/learn/advanced-development/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00",
"app/learn/advanced-development/admin/page.mdx": "2024-10-07T12:39:13.178Z",

View File

@@ -392,8 +392,9 @@ export const sidebar = numberSidebarItems(
title: "Events Data Payload",
},
{
type: "link",
path: "/learn/advanced-development/events-and-subscribers/emit-event",
title: "Emit an Event",
title: "Emit Event",
},
],
},