import { TypeList } from "docs-ui"

export const metadata = {
  title: `${pageNumber} Queryable Modules`,
}

# {metadata.title}

In this chapter, you’ll learn what a queryable module is and how to configure a module to be queryable.

## What is a Queryable Module?

A queryable module is one whose data can be queried more flexibly and referenced in other modules.

By making a module queryable, you can fetch its data using object and GraphQL syntax without using the main service’s methods.

<Note title="Use queryable modules when" type="success">

- You want more flexibility when fetching data.
- You’re creating relations between modules and querying data across modules.

</Note>

---

## How to Make a Module Queryable

<Note title="Steps Summary">

1. Configure module to be queryable.
2. Add `__joinerConfig` method to main service.

</Note>

### 1. Adjust Module Configuration

To make a module queryable, adjust its configuration object passed to the `modules` object in `medusa-config.js`. The configuration object accepts a `definition` property, whose value is an object of advanced module configurations.

For example:

export const configHighlights = [
  ["5", "key", "The module's key in the `modules` object."],
  ["6", "registrationName", "The name that the main service is registered under in the Medusa container. It’s recommended to be the same as `key`'s value."],
  ["7", "isQueryable", "Whether the module is queryable."]
]

```js title="medusa-config.js" highlights={configHighlights}
const modules = {
  helloModuleService: {
    resolve: "./dist/modules/hello",
    definition: {
      key: "helloModuleService",
      registrationName: "helloModuleService",
      isQueryable: true,
    },
  },
  // ...
}
```

The `definition` property’s value accepts the following properties, among others:

<TypeList types={[
  {
    name: "key",
    type: "`string`",
    optional: false,
    description: "The module's key in the `modules` object."
  },
  {
    name: "registrationName",
    type: "`string`",
    optional: false,
    description: "The name that the main service is registered under in the Medusa container. It’s recommended to be the same as `key`'s value.",
  },
  {
    name: "isQueryable",
    type: "`boolean`",
    description: "Whether the module is queryable."
  }
]} sectionTitle="Adjust Module Configuration" />

### 2. Define `__joinerConfig` Method

Queryable modules must define a public `__joinerConfig` method in their main service. This method returns an object that defines how a module’s data can be accessed and referenced.

Create the file `src/modules/hello/joiner-config.ts` with the following content:

```ts title="src/modules/hello/joiner-config.ts"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MyCustom } from "./models/my-custom"

const joinerConfig: ModuleJoinerConfig = {
  serviceName: "helloModuleService",
  primaryKeys: ["id"],
  alias: [
    {
      name: ["my_custom"],
      args: {
        entity: MyCustom.name,
      },
    },
  ],
}

export default joinerConfig
```

The `joinerConfig` object of type `ModuleJoinerConfig` imported from `@medusajs/types` accepts the following properties:

<TypeList types={[
  {
    name: "serviceName",
    type: "`string`",
    optional: false,
    description: "The name of the main module service as registered in the Medusa container."
  },
  {
    name: "primaryKeys",
    type: "`string[]`",
    optional: false,
    description: "The primary key field names used in the data models of the module.",
  },
  {
    name: "alias",
    type: "`object[]`",
    description: "The alias definitions for each data model in the module.",
    children: [
      {
        name: "name",
        type: "`string[]`",
        description: "The alias names used later when fetching or referencing the data in the model."
      },
      {
        name: "args",
        type: "`object`",
        description: "The alias's arguments.",
        children: [
          {
            name: "entity",
            type: "string",
            description: "The name of the data model this alias is defined for."
          }
        ]
      }
    ]
  }
]} sectionTitle="Define __joinerConfig Method" />

Then, import that file in `src/modules/hello/service.ts` and add a new `__joinerConfig` method:

```ts title="src/modules/hello/service.ts" highlights={[["3"], ["14"], ["15"], ["16"]]}
// other imports...
import { ModuleJoinerConfig } from "@medusajs/types"
import joinerConfig from "./joiner-config"

class HelloModuleService extends ModulesSdkUtils
  .abstractModuleServiceFactory<
    // ...
  >(
    // ...
  ) {
  
    // ...
  
    __joinerConfig(): ModuleJoinerConfig {
      return joinerConfig
    }
    
    // ...
}
```

---

## Querying a Queryable Module

The next chapter explains how to query the data of a Queryable module.
