3.3. Module Link
In this chapter, you’ll learn what a module link is and how to define one.
What is a Module Link?#
Medusa's modular architecture isolates modules from one another to ensure they can be integrated into your application without side effects. Module isolation has other benefits, which you can learn about in the Module Isolation chapter. Since modules are isolated, you can't access another module's data models to add a relation to it or extend it. Instead, you use a module link.
A module link forms an association between two data models of different modules while maintaining module isolation. Using module links, you can build virtual relations between your custom data models and data models in the commerce modules, which is useful as you extend the features provided by the commerce modules. Then, Medusa creates a link table in the database to store the IDs of the linked records. You'll learn more about link tables later in this chapter.
For example, the Brand Customizations Tutorial shows how to create a Brand Module that adds the concept of brands to your application, then link those brands to a product.
How to Define a Module Link?#
1. Create Link File#
Module links are defined in a TypeScript or JavaScript file under the src/links
directory. The file defines the link using defineLink
from the Modules SDK and exports it.
For example:
The defineLink
function accepts as parameters the link configurations of each module's data model. A module has a special linkable
property that holds these configurations for its data models.
In this example, you define a module link between the blog
module's post
data model and the Product Module's Product
data model.
2. Sync Links#
After defining the link, run the db:sync-links
command:
The Medusa application creates a new table for your module link to store the IDs of linked records.
You can also use the db:migrate
command, which runs both the migrations and syncs the links.
Use either of these commands whenever you make changes to your link definitions. For example, run this command if you remove your link definition file.
Module Link's Database Table#
When you define a module link, the Medusa application creates a table in the database for that module link. The table's name is a combination of the names of the two data models linked in the format module1_table1_module2_table2
, where:
module1
andmodule2
are the names of the modules.table1
andtable2
are the table names of the data models.
For example, if you define a link between the Product
data model from the Product Module and a Post
data model from a Blog Module, the table name would be product_product_blog_post
.
The table has two columns, each storing the ID of a record from the linked data models. For example, the product_product_blog_post
table would have columns product_id
and post_id
. These columns store only the IDs of the linked records and do not hold a foreign key constraint.
Then, when you create links between records of the data models, the IDs of these data models are stored as a new record in the link's table.
When to Use Module Links#
- You want to create a relation between data models from different modules.
- You want to extend the data model of another module.
Define a List Module Link#
By default, a module link establishes a one-to-one relation: a record of a data model is linked to one record of the other data model.
To specify that a data model can have multiple of its records linked to the other data model's record, use the isList
option.
For example:
In this case, you pass an object of configuration as a parameter instead. The object accepts the following properties:
linkable
: The data model's link configuration.isList
: Whether multiple records can be linked to one record of the other data model.
In this example, a record of product
can be linked to more than one record of post
.
Many-to-Many Module Link#
Your module link can also establish a many-to-many relation between the linked data models. To do this, enable isList
on both sides of the link.
For example:
1import BlogModule from "../modules/blog"2import ProductModule from "@medusajs/medusa/product"3import { defineLink } from "@medusajs/framework/utils"4 5export default defineLink(6 {7 linkable: ProductModule.linkable.product,8 isList: true,9 },10 {11 linkable: BlogModule.linkable.post,12 isList: true,13 }14)
Set Delete Cascades on Link#
To enable delete cascade on a link so that when a record is deleted, its linked records are also deleted, pass the deleteCascade
property in the object passed to defineLink
.
For example:
In this example, when a product is deleted, its linked post
record is also deleted.
Renaming Participants in a Module Link#
As mentioned in the Module Link's Database Table section, the name of a link's table consists of the names of the modules and the data models' table names.
So, if you rename a module or a data model's table, then run the db:sync-links
or db:migrate
commands, you'll be asked to delete the old link table and create a new one.
model.define
, and a module's name is passed in the first parameter of Module
in the module's index.ts
file.For example, if you have the link table product_product_blog_post
and you rename the Blog Module from blog
to article
, Medusa considers the old link definition deleted. Then, when you run the db:sync-links
or db:migrate
command, Medusa will ask if you want to delete the old link table, and will create a new one with the new name product_product_article_post
.
To resolve this, you can rename the link table in the link definition.
Rename Link Table#
If you need to rename a module or its data model's table, you can persist the old name by passing a third parameter to defineLink
. This parameter is an object of additional configurations. It accepts a database
property that allows you to configure the link's table name.
For example, after renaming the Blog Module to article
, you can persist the old name blog
in the link table name:
1import ArticleModule from "../modules/article"2import ProductModule from "@medusajs/medusa/product"3import { defineLink } from "@medusajs/framework/utils"4 5export default defineLink(6 ProductModule.linkable.product,7 {8 linkable: ArticleModule.linkable.post,9 isList: true,10 },11 {12 database: {13 table: "product_product_blog_post",14 },15 }16)
In this example, you set the table
property in the database
object to the old link table name product_product_blog_post
, ensuring that the old link table is not deleted.
This is enough to rename the link table when you rename a module. If you renamed a data model's table, you need to also run the db:sync-links
or db:migrate
commands, which will update the column names in the link table automatically:
Delete Module Link Definition#
To delete a module link definition, remove the link file from the src/links
directory. Then, run the db:sync-links
or db:migrate
command to delete the link table from the database: