Today, we are announcing a significant update and change to the events system of Medusa. We are moving part of the Event Bus from the core package to a separate module. Our continuous efforts to build a more modular and flexible engine motivate the decision.
In a space with continuous innovations and fierce competition, the ability to adapt your product to changes, run experiments, and leverage new technology becomes highly relevant for businesses to stay ahead (or keep up) with the competition.
To do so, you need flexibility in your setup.
At Medusa, we strive to provide merchants and developers with the building blocks to create bespoke experiences. These building blocks give you a strong starting point and are created to be replaced with more advanced functionality as your business grows, and your needs change.
The flexibility and ease of customization enable businesses to focus on building the best product for their customers without worrying about the typical triennial migration project.
The Event Bus modules give businesses the freedom to choose the technology to power the events system of Medusa.
What are modules?
Until now, Medusa has offered two ways of extending or replacing core functionality with custom implementations or third-party services; through Strategies and Plugins.
Strategies allow you to override an isolated piece of business logic e.g. cart completion or product import, and plugins are used to build custom features or integrate services with your engine. The latter is especially well-suited for when you want several of the same type of services installed, e.g. payment providers.
Modules allow you to replace business domains or specific elements in your stack with pre-built functionality, custom implementations, or third-party providers. They can be shipped through Copy to clipboardnpm
and are configurable in Copy to clipboardmedusa-config.js
- similar to plugins.
The main difference between Modules and Strategies and Plugins, in the context of business domains, is that Modules do not necessarily share application scope and resources with the core. Effectively, this means that a module can live without dependencies on core concepts and be powered by a separate data store.
This unlocks a multitude of opportunities, as you can power entire domains of Medusa with third-party APIs or custom implementations that fit your organization’s needs. Let’s take user authentication as an example. Separating the Users domain into a module will allow businesses to use providers like Okta to manage everything related to users, authentication, roles, etc. - without shoehorning an existing feature to work correctly through an integration.
Refer to our documentation for a detailed walkthrough of the Modules API, including setup and building one yourself. In this post, we only briefly explain simple usage and configuration.
Event Bus module
One of the first use cases of modules is within the events' domain. We are introducing an Event Bus module enabling businesses to use any available pub/sub technology to power the message broker of Medusa.
We still offer a fully functional event bus powered by Redis out-of-the-box, but instead of being baked into the core, you must install and configure it.
Additionally, we are replacing the default event bus, which previously used a mocked Redis instance, with a local event bus module powered by the Node EventEmitter. This module is not recommended for a production environment.
You’ll find more details about the Redis event bus functionality and configuration in the documentation.
Installation
The following steps should be taken to install the Redis Event Bus and upgrade your existing setup to use the Modules API.
These are the required steps for any module going forward - unless the module comes with a default package; in that case, you only need to install the Copy to clipboardnpm
package in your Medusa project.
Installing the Redis Event Bus
Install the Redis event bus with Copy to clipboardnpm
:
1yarn add @medusajs/event-bus-redis
Configure it in Copy to clipboardmedusa-config.js
:
123456789101112131415module.exports = {projectConfig: {database_url: DATABASE_URL,...},modules: {eventBus: {resolve: "@medusajs/event-bus-redis",options: {redisUrl: "redis://...",},},},plugins: ["medusa-payment-stripe"],};
Again, we won’t cover the details of the configuration in depth - our documentation serves that purpose - but only briefly explain the code snippet above.
We use the new Copy to clipboardmodules
property on the project configuration object to specify the modules we want to override or add. The keys of this object are defined and exposed in the core, ensuring that modules are correctly registered.
The module key for the event bus is, you guessed it, Copy to clipboardeventBus
. The value of the key is the module configuration. The Copy to clipboardresolve
property points to the package you want to use and can be an Copy to clipboardnpm
package or a path to a local implementation.
The Copy to clipboardoptions
property is a set of required and optional settings that are injected into the module. The only required property for the Redis Event Bus is the URL of your Redis instance. Other optional settings can be found in the documentation.
After performing these steps, you can restart your Medusa instance, and everything will work as always, but your events system will be configured and powered by our Modules API.
Summary
The Modules API is a huge step toward a more composable architecture and will play a critical role in all our work as we advance. The Event Bus module is one of the first demonstrations of the API’s capabilities, though it does not do it full justice. The full power of the API will be more evident as we move into the business domains e.g. multi-warehousing. Read the product announcement here.
The Event Bus module abstraction is valuable for products and companies that use Medusa as part of their larger system, as they typically have existing messaging infrastructure in place. Giving them the ability to use this infrastructure to power events in Medusa will make the integration easier and reduce costs and stack complexity.
The abstraction is also valuable for developers unfamiliar with Redis or BullMQ (our message queue library). It allows them to replace the technology of the events system with a framework they are more comfortable with, thus offering a better developer experience.
You can learn more about the events system in our documentation
Give the new modules a try, and let us know what you think. Feedback is highly appreciated.