3.7.7. Expose a Workflow Hook

In this chapter, you'll learn how to expose a hook in your workflow.

Note: Refer to the Workflow Hooks chapter to learn what a workflow hook is and how to consume Medusa's workflow hooks.

When to Expose a Hook?#

Medusa exposes hooks in many of its workflows to allow you to inject custom functionality.

You can also expose your own hooks in your workflows to allow other developers to consume them. This is useful when you're creating a workflow in a plugin and you want plugin users to extend the workflow's functionality.

For example, you are creating a blog plugin and you want to allow developers to perform custom validation before a blog post is created. You can expose a hook in your workflow that developers can consume to perform their custom validation.

If your workflow is not in a plugin, you probably don't need to expose a hook as you can perform the necessary actions directly in the workflow.


How to Expose a Hook in a Workflow?#

To expose a hook in your workflow, use createHook from the Workflows SDK.

For example:

src/workflows/create-blog-post/index.ts
1import {2  createStep,3  createHook,4  createWorkflow,5  WorkflowResponse,6} from "@medusajs/framework/workflows-sdk"7import { createPostStep } from "./steps/create-post"8
9export const createBlogPostWorkflow = createWorkflow(10  "create-blog-post", 11  function (input) {12    const validate = createHook(13      "validate", 14      { post: input }15    )16    const post = createPostStep(input)17
18    return new WorkflowResponse(post, {19      hooks: [validate],20    })21  }22)

The createHook function accepts two parameters:

  1. The first is a string indicating the hook's name. Developers consuming the hook will use this name to access the hook.
  2. The second is the input to pass to the hook handler. Developers consuming the hook will receive this input in the hook handler.

You must also return the hook in the workflow's response by passing a hooks property to the WorkflowResponse's second parameter object. Its value is an array of the workflow's hooks.

How to Consume the Hook?#

To consume the hook of the workflow, create the file src/workflows/hooks/create-blog-post.ts with the following content:

src/workflows/hooks/create-blog-post.ts
1import { MedusaError } from "@medusajs/framework/utils"2import { createBlogPostWorkflow } from "../create-blog-post"3
4createBlogPostWorkflow.hooks.validate(5  async ({ post }, { container }) => {6    // TODO perform an action7    if (!post.additional_data.custom_title) {8      throw new MedusaError(9        MedusaError.Types.INVALID_DATA,10        "Custom title is required"11      )12    }13  }14)

The hook is available on the workflow's hooks property using its name validate.

You invoke the hook, passing a step function (the hook handler) as a parameter.

The hook handler is essentially a step function. You can perform in it any actions you perform in a step. For example, you can throw an error, which would stop the workflow execution.

You can also access the Medusa container in the hook handler to perform actions like using Query or module services.

For example:

src/workflows/hooks/create-blog-post.ts
1import { createBlogPostWorkflow } from "../create-blog-post"2
3createBlogPostWorkflow.hooks.validate(4  async ({ post }, { container }) => {5    const query = container.resolve("query")6
7    const { data: existingPosts } = await query.graph({8      entity: "post",9      fields: ["*"],10    })11
12    // TODO do something with existing posts...13  }14)

Learn more about the hook handler in the Workflow Hooks chapter.

Was this chapter helpful?
Ask Anything
FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break