3.4.1. Integrate Third-Party Brand System in a Service

Example ChapterThis chapter covers how to integrate a dummy third-party system in a service as a step of the "Integrate Systems" chapter .

1. Create Service#

Start by creating the file src/modules/brand/services/client.ts with the following content:

src/modules/brand/services/client.ts
1import { Logger, ConfigModule } from "@medusajs/framework/types"2import { BRAND_MODULE } from ".."3
4export type BrandClientOptions = {5  apiKey: string6}7
8type InjectedDependencies = {9  logger: Logger10  configModule: ConfigModule11}12
13export class BrandClient {14  private options_: BrandClientOptions15  private logger_: Logger16
17  constructor({ logger, configModule }: InjectedDependencies) {18    this.logger_ = logger19
20    const moduleDef = configModule.modules[BRAND_MODULE]21    if (typeof moduleDef !== "boolean") {22      this.options_ = moduleDef.options as BrandClientOptions23    }24  }25}

This creates a BrandClient service. Using dependency injection, you resolve the logger and configModule from the Module's container.

logger is useful to log messages, and configModule has configurations exported in medusa-config.ts.

You also define an options_ property in your service to store the module's options.

The configModule's modules property is an object whose keys are registered module names and values are the module's configuration.

If the module's configuration isn't a boolean, it has an options property that holds the module's options. You use it to set the options_ property's value.

TipIf the service integrating the third-party system was a main service, it receives the module's options as a second parameter.

Integration Methods#

Next, add the following methods to simulate sending requests to the third-party system:

src/modules/brand/services/client.ts
1// other imports...2import { InferTypeOf } from "@medusajs/framework/types"3import { Brand } from "../models/brand"4
5export class BrandClient {6  // ...7
8  // a dummy method to simulate sending a request,9  // in a realistic scenario, you'd use an SDK, fetch, or axios clients10  private async sendRequest(url: string, method: string, data?: any) {11    this.logger_.info(`Sending a ${12      method13    } request to ${url}. data: ${JSON.stringify(data, null, 2)}`)14    this.logger_.info(`Client Options: ${15      JSON.stringify(this.options_, null, 2)16    }`)17  }18
19  async createBrand(brand: InferTypeOf<typeof Brand>) {20    await this.sendRequest("/brands", "POST", brand)21  }22
23  async deleteBrand(id: string) {24    await this.sendRequest(`/brands/${id}`, "DELETE")25  }26
27  async retrieveBrands() {28    await this.sendRequest("/brands", "GET")29
30    return []31  }32}

The sendRequest method is a dummy method to simulate sending a request to a third-party system.

You also add three methods that use the sendRequest method:

  • createBrand that creates a brand in the third-party system. To reference a brand's type, you use the InferTypeOf utility imported from @medusajs/framework/types. This transforms a data model, which is a variable, to its equivalent type.
  • deleteBrand that deletes the brand in the third-party system.
  • retrieveBrands to retrieve a brand from the third-party system.

2. Export Service#

If the service integrating the third-party system is the module's main service, you only need to export it in the module definition.

However, since this service is an internal service in the Brand Module, you must export it in a src/modules/brand/services/index.ts file:

src/modules/brand/services/index.ts
export * from "./client"

This registers the service in the module's container, allowing you to access it in the module's main service.


3. Add Internal Service in Main Service#

In the main service at src/modules/brand/service.ts, add the following imports and types at the top of the file:

src/modules/brand/service.ts
1// other imports...2import { BrandClient, BrandClientOptions } from "./services"3
4type InjectedDependencies = {5  brandClient: BrandClient6}

Then, add the following in the BrandModuleService class:

src/modules/brand/service.ts
1class BrandModuleService extends MedusaService({2  Brand,3}) {4  public client: BrandClient5
6  constructor({ brandClient }: InjectedDependencies) {7    super(...arguments)8
9    this.client = brandClient10  }11}

In the main module service, you first resolve through dependency injection the brandClient from the container and set it in a public property client.


4. Pass Options to the Module#

To pass options in the module, change its configurations in medusa-config.ts:

medusa-config.ts
1module.exports = defineConfig({2  // ...3  modules: [4    {5      resolve: "./src/modules/brand",6      options: {7        apiKey: process.env.BRAND_API_KEY || "temp",8      },9    },10  ], 11})

A module's configuration accepts an options property, which can hold any options to pass to the module.


Next Steps: Sync Brand From Medusa to Third-Party System#

In the next chapter, you'll learn how to sync brands created in Medusa to the third-party system using a workflow and a scheduled job.

Was this chapter helpful?
Edit this page