docs: revise create brand workflow (#10346)
* docs: revise create brand workflow * small fix
This commit is contained in:
1 parent
d57c739052
commit
aca7907d81
4 files changed
+73
-67
No files matched your search
@@ -179,4 +179,4 @@ The `db:generate` command accepts as an argument the name of the module to gener
|
||||
|
||||
The Brand Module now creates a `brand` table in the database and provides a class to manage its records.
|
||||
|
||||
In the next step, you'll implement the functionality to create a brand in a workflow. You'll then use that workflow in a later chapter to expose an endpoint that allows admin users to create a brand.
|
||||
In the next chapter, you'll implement the functionality to create a brand in a workflow. You'll then use that workflow in a later chapter to expose an endpoint that allows admin users to create a brand.
|
||||
@@ -1,35 +1,23 @@
|
||||
import { Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `${pageNumber} Define Workflow to Create a Brand`,
|
||||
title: `${pageNumber} Guide: Create Brand Workflow`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
<Note title="Example Chapter">
|
||||
This chapter is a follow-up to the [previous one](../module/page.mdx) where you created a Brand Module. In this chapter, you'll create a workflow that creates a brand.
|
||||
|
||||
This chapter covers how to define a workflow that creates a brand as part of the ["Build Custom Features" chapter](../page.mdx).
|
||||
You implement commerce features within workflows. A workflow is a series of queries and actions, called steps, that complete a task. You construct a workflow similar to a regular function, but it's a special function that allows you to define roll-back logic, retry configurations, and more advanced features.
|
||||
|
||||
</Note>
|
||||
|
||||
## 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.
|
||||
The workflow you'll create in this chapter will use the Brand Module's service to implement the feature of creating a brand. In the [next chapter](../api-route/page.mdx), you'll expose an API route that allows admin users to create a brand, and you'll use this workflow in the route's implementation.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about workflows [in this guide](../../../basics/workflows/page.mdx).
|
||||
Learn more about workflows in [this chapter](../../../basics/workflows/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
This is even more useful when you create workflows with many steps, or integrate third-party systems.
|
||||
|
||||
---
|
||||
|
||||
## Create createBrandWorkflow
|
||||
|
||||
<Prerequisites
|
||||
items={[
|
||||
{
|
||||
@@ -39,46 +27,29 @@ This is even more useful when you create workflows with many steps, or integrate
|
||||
]}
|
||||
/>
|
||||
|
||||
Create the file `src/workflows/create-brand/index.ts` with the following content:
|
||||
|
||||
```ts
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
export type CreateBrandInput = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export const createBrandWorkflow = createWorkflow(
|
||||
"create-brand",
|
||||
(input: CreateBrandInput) => {
|
||||
// TODO
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
For now, this workflow only defines its input. You'll create its step and use it in the workflow.
|
||||
|
||||
---
|
||||
|
||||
## Create createBrandStep
|
||||
## 1. Create createBrandStep
|
||||
|
||||
Create the file `src/workflows/create-brand/steps/create-brand.ts` with the following content:
|
||||
A workflow consists of a series of steps, each step created in a TypeScript or JavaScript file under the `src/workflows` directory. A step is defined using the `createStep` utility function imported from `@medusajs/framework/workflows-sdk`.
|
||||
|
||||
```ts title="src/workflows/create-brand/steps/create-brand.ts" collapsibleLines="1-8" expandButtonLabel="Show Imports"
|
||||
The workflow you're creating in this guide has one step to create the brand. So, create the file `src/workflows/create-brand/steps/create-brand.ts` with the following content:
|
||||
|
||||
```ts title="src/workflows/create-brand/steps/create-brand.ts"
|
||||
import {
|
||||
createStep,
|
||||
StepResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { CreateBrandInput } from ".."
|
||||
import { BRAND_MODULE } from "../../../modules/brand"
|
||||
import BrandModuleService from "../../../modules/brand/service"
|
||||
|
||||
export type CreateBrandStepInput = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export const createBrandStep = createStep(
|
||||
"create-brand-step",
|
||||
async (input: CreateBrandInput, { container }) => {
|
||||
async (input: CreateBrandStepInput, { container }) => {
|
||||
const brandModuleService: BrandModuleService = container.resolve(
|
||||
BRAND_MODULE
|
||||
)
|
||||
@@ -90,17 +61,33 @@ export const createBrandStep = createStep(
|
||||
)
|
||||
```
|
||||
|
||||
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.
|
||||
You create a `createBrandStep` using the `createStep` function. It accepts the step's unique name as a first parameter, and the step's function as a second parameter.
|
||||
|
||||
The step returns the created brand in the first parameter of the `StepResponse`'s constructor.
|
||||
The step function receives two parameters: input passed to the step when it's invoked, and an object of general context and configurations. This object has a `container` property, which is the Medusa container.
|
||||
|
||||
The [Medusa container](../../../basics/medusa-container/page.mdx) is a registry of framework and commerce tools accessible in your customizations, such as a workflow's step. The Medusa application registers the services of core and custom modules in the container, allowing you to resolve and use them.
|
||||
|
||||
So, In the step function, you use the Medusa container to resolve the Brand Module's service and use its generated `createBrands` method, which accepts an object of brands to create.
|
||||
|
||||
<Note>
|
||||
|
||||
Learn more about the generated `create` method's usage in [this reference](!resources!/service-factory-reference/methods/create).
|
||||
|
||||
</Note>
|
||||
|
||||
A step must return an instance of `StepResponse`. Its first parameter is the data returned by the step, and the second is the data passed to the compensation function, which you'll learn about next.
|
||||
|
||||
### Add Compensation Function to Step
|
||||
|
||||
A compensation function rolls back changes made by the step if an error occurs in the workflow.
|
||||
You define for each step a compensation function that's executed when an error occurs in the workflow. The compensation function defines the logic to roll-back the changes made by the step. This ensures your data remains consistent if an error occurs, which is especially useful when you integrate third-party services.
|
||||
|
||||
The second parameter of the `StepResponse`'s constructor is passed to the compensation function.
|
||||
<Note>
|
||||
|
||||
To add the compensation function, pass a third parameter to `createStep`:
|
||||
Learn more about the compensation function in [this chapter](../../../advanced-development/workflows/compensation-function/page.mdx).
|
||||
|
||||
</Note>
|
||||
|
||||
To add a compensation function to the `createBrandStep`, pass it as a third parameter to `createStep`:
|
||||
|
||||
```ts title="src/workflows/create-brand/steps/create-brand.ts"
|
||||
export const createBrandStep = createStep(
|
||||
@@ -115,38 +102,57 @@ export const createBrandStep = createStep(
|
||||
)
|
||||
```
|
||||
|
||||
You resolve the Brand Module's main service and use its generated `deleteBrands` method to delete the brand created by the step.
|
||||
The compensation function's first parameter is the brand's ID which you passed as a second parameter to the step function's returned `StepResponse`. It also accepts a context object with a `container` property as a second parameter, similar to the step function.
|
||||
|
||||
<Note title="Tip">
|
||||
In the compensation function, you resolve the Brand Module's service from the Medusa container, then use its generated `deleteBrands` method to delete the brand created by the step. This method accepts the ID of the brand to delete.
|
||||
|
||||
The `deleteBrands` method accepts an ID or an array of IDs of brands to delete.
|
||||
<Note>
|
||||
|
||||
Learn more about the generated `delete` method's usage in [this reference](!resources!/service-factory-reference/methods/delete).
|
||||
|
||||
</Note>
|
||||
|
||||
So, when an error occurs during the workflow, the brand that was created by the step is deleted to maintain data consistency.
|
||||
So, if an error occurs during the workflow's execution, the brand that was created by the step is deleted to maintain data consistency.
|
||||
|
||||
---
|
||||
|
||||
## Add Step to Workflow
|
||||
## 2. Create createBrandWorkflow
|
||||
|
||||
Go back to the workflow at `src/workflows/create-brand/index.ts` and import the step you created:
|
||||
You can now create the workflow that runs the `createBrandStep`. A workflow is created in a TypeScript or JavaScript file under the `src/workflows` directory. In the file, you use the `createWorkflow` function imported from `@medusajs/framework/workflows-sdk` to create the workflow.
|
||||
|
||||
So, create the file `src/workflows/create-brand/index.ts` with the following content:
|
||||
|
||||
```ts
|
||||
import {
|
||||
createWorkflow,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
import { createBrandStep } from "./steps/create-brand"
|
||||
|
||||
type CreateBrandInput = {
|
||||
name: string
|
||||
}
|
||||
|
||||
export const createBrandWorkflow = createWorkflow(
|
||||
"create-brand",
|
||||
(input: CreateBrandInput) => {
|
||||
const brand = createBrandStep(input)
|
||||
|
||||
return new WorkflowResponse(brand)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
Then, replace the `TODO` with the following:
|
||||
You create the `createBrandWorkflow` using the `createWorkflow` function. This function accepts two parameters: the workflow's unique name, and the workflow's constructor function holding the workflow's implementation.
|
||||
|
||||
```ts
|
||||
const brand = createBrandStep(input)
|
||||
The constructor function accepts the workflow's input as a parameter. In the function, you invoke the `createBrandStep` you created in the previous step to create a brand.
|
||||
|
||||
return new WorkflowResponse(brand)
|
||||
```
|
||||
|
||||
You use the `createBrandStep` to create the brand and return it in the workflow's response.
|
||||
A workflow must return an instance of `WorkflowResponse`. It accepts as a parameter the data to return to the workflow's executor.
|
||||
|
||||
---
|
||||
|
||||
## Next Step: Create Brand API Route
|
||||
## Next Steps: Expose 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.
|
||||
You now have a `createBrandWorkflow` that you can execute to create a brand.
|
||||
|
||||
In the next chapter, you'll add an API route that allows admin users to create a brand. You'll learn how to create the API route, and execute in it the workflow you implemented in this chapter.
|
||||
@@ -91,7 +91,7 @@ export const generatedEditDates = {
|
||||
"app/learn/advanced-development/workflows/variable-manipulation/page.mdx": "2024-11-14T16:11:24.538Z",
|
||||
"app/learn/customization/custom-features/api-route/page.mdx": "2024-09-12T12:42:34.201Z",
|
||||
"app/learn/customization/custom-features/module/page.mdx": "2024-11-28T09:25:29.098Z",
|
||||
"app/learn/customization/custom-features/workflow/page.mdx": "2024-09-30T08:43:53.133Z",
|
||||
"app/learn/customization/custom-features/workflow/page.mdx": "2024-11-28T10:47:28.084Z",
|
||||
"app/learn/customization/extend-models/create-links/page.mdx": "2024-09-30T08:43:53.133Z",
|
||||
"app/learn/customization/extend-models/extend-create-product/page.mdx": "2024-09-30T08:43:53.134Z",
|
||||
"app/learn/customization/custom-features/page.mdx": "2024-11-28T08:21:55.207Z",
|
||||
|
||||
@@ -103,7 +103,7 @@ export const sidebar = numberSidebarItems(
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
title: "Create Brand Workflow",
|
||||
title: "Brand Workflow",
|
||||
path: "/learn/customization/custom-features/workflow",
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user