import { TypeList, CodeTabs, CodeTab } from "docs-ui" export const metadata = { title: `${pageNumber} Module Relationships`, } # {metadata.title} In this document, you’ll learn about creating relationships between modules. ## What is a Module Relationship? A module can have a relationship to another module in the form of a reference. The Medusa application resolves these relationships while maintaining isolation between the modules and allowing you to retrieve data across them. - You want to build relationships between the data models of modules. - You want to assoaciate more fields with the data model of another module. - You’re building relationships between data models in the same module. Use foreign keys instead. --- ## How to Create a Module Relationship? 1. Define a `__joinerConfig` method in the module's main service. 2. Configure module to be queryable. Consider you’re creating a data model that adds custom fields associated with a product: ```ts title="src/modules/hello/models/custom-product-data.ts" highlights={[["17"]]} import { BaseEntity } from "@medusajs/utils" import { Entity, PrimaryKey, Property, } from "@mikro-orm/core" @Entity() export class CustomProductData extends BaseEntity { @PrimaryKey({ columnType: "text" }) id!: string @Property({ columnType: "text" }) custom_field: string @Property({ columnType: "text", nullable: true }) product_id?: string } ``` The `CustomProductData` data model has a `product_id` field to reference the product it adds custom fields for. When you add a new data model, make sure to: - [Create a migration for it.](../../../basics/data-models/page.mdx#create-a-migration) - [Add it to the second parameter of the main service's factory function.](../service-factory/page.mdx#abstractModuleServiceFactory-parameters) ### 1. Define `__joinerConfig` Method To create a relationship to the `product` data model of the Product Module, create a public `__joinerConfig` method in your main module's service: export const relationshipsHighlight = [ ["39", "serviceName", "The name of the module that this relationship is referencing."], ["40", "alias", "The alias of the data model you’re referencing in the other module."], ["41", "primaryKey", "The name of the field you’re referencing in the other module’s data model."], ["42", "foreignKey", "The name of the field in your data models referencing the other module’s model."], ] ```ts title="src/modules/hello/service.ts" highlights={relationshipsHighlight} // other imports... import { MyCustom } from "./models/custom-product-data" import { CustomProductData } from "./models/custom-product-data" import { ModuleJoinerConfig } from "@medusajs/types" import { Modules } from "@medusajs/modules-sdk" class HelloModuleService extends ModulesSdkUtils .abstractModuleServiceFactory< // ... >( // ... ) { // ... __joinerConfig(): ModuleJoinerConfig { return { serviceName: "helloModuleService", alias: [ { name: ["my_custom"], args: { entity: MyCustom.name, }, }, { name: ["custom_product_data"], args: { entity: CustomProductData.name, // Only needed if data model isn't main data model // of service methodSuffix: "CustomProductDatas", }, }, ], relationships: [ { serviceName: Modules.PRODUCT, alias: "product", primaryKey: "id", foreignKey: "product_id", }, ], } } // ... } ``` This creates a relationship to the `Product` data model of the Product Module using the alias `product`. The `product_id` fields in your data models are considered references to the `id` field of the `Product` data model. #### `__joinerConfig` Return Type ### 2. Adjust Module Configuration To use relationships in a module, adjust its configuration object passed to the `modules` object in `medusa-config.js`: export const configHighlights = [ ["7", "isQueryable", "Enable this property to use relationships in a module."] ] ```js title="medusa-config.js" highlights={configHighlights} const modules = { helloModuleService: { // ... definition: { isQueryable: true, }, }, // ... } ``` Enabling the `isQueryable` property is required to use relationships in a module. --- ## Reference Inner Data Models If the data model you’re referencing isn’t the main data model of the main module service, pass to the relationship definition the `args` property: ```ts title="src/modules/hello/service.ts" highlights={[["20", "methodSuffix", "The suffix of the referenced data model's methods."]]} class HelloModuleService extends ModulesSdkUtils .abstractModuleServiceFactory< // ... >( // ... ) { // ... __joinerConfig(): ModuleJoinerConfig { return { // ... relationships: [ { serviceName: Modules.PRODUCT, primaryKey: "id", foreignKey: "variant_id", alias: "variant", args: { methodSuffix: "Variants", }, }, ], } } } ``` The `args` property’s value is an object accepting a `methodSuffix` property. The `methodSuffix` property’s value is the plural name of the data model. --- ## Querying Module Relationships The next chapter explains how to query data across module relationships.