> For the complete documentation index, see [llms.txt](https://gruntsass.gitbook.io/template-api-nodejs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gruntsass.gitbook.io/template-api-nodejs/nodejs/premium-template-rest-api/dynamic-module/create-or-import-module.md).

# Create or Import Module

***

### Prerequisites

There are a few prerequisites for your module to be recognized:

1. The `@DynamicModule({})` decorator must be added to the module.
2. The `.ts` file must end with `.module.ts`.

***

### Example Usage

When you move this module into a designated folder like `src/modules`, it can be automatically loaded by your dynamic loading service. The controller exposes two endpoints to test the API:

This module example can serve as a foundation in the documentation to explain how to create a simple module in NestJS while adhering to SOLID principles and the modular architecture of your API.

***

### Component Explanation

**MyCustomModule**: The main module that encapsulates the controller and the service.

```javascript
import { Module } from '@nestjs/common';
import { MyCustomService } from './services/my-custom.service';
import { MyCustomController } from './controllers/my-custom.controller';
import { DynamicModule } from '../../common/decorators/dynamic.module.decorator';

@DynamicModule({})
@Module({
  controllers: [MyCustomController],
  providers: [MyCustomService],
})
export class MyCustomModule {}
```

**MyCustomController**: Responsible for handling incoming HTTP requests. It provides two routes:

* `GET /mycustom` to retrieve all entries.
* `POST /mycustom` to create a new entry.

```javascript
import { Controller, Get, Post, Body } from '@nestjs/common';
import { MyCustomService } from '../services/my-custom.service';
import { CreateMyCustomDto } from '../dto/create-my-custom.dto';

@Controller('mycustom')
export class MyCustomController {
  constructor(private readonly myCustomService: MyCustomService) {}

  @Get()
  findAll() {
    return this.myCustomService.findAll();
  }

  @Post()
  create(@Body() createMyCustomDto: CreateMyCustomDto) {
    return this.myCustomService.create(createMyCustomDto);
  }
}
```

**MyCustomService**: Handles the business logic related to "MyCustom" entities, storing data in memory and allowing creation and retrieval operations.

```javascript
import { Injectable } from '@nestjs/common';
import { MyCustomServiceInterface } from '../interfaces/my-custom-service.interface';
import { CreateMyCustomDto } from '../dto/create-my-custom.dto';

@Injectable()
export class MyCustomService implements MyCustomServiceInterface {
  private items = [];

  findAll() {
    return this.items;
  }

  create(createMyCustomDto: CreateMyCustomDto) {
    const newItem = { id: Date.now(), ...createMyCustomDto };
    this.items.push(newItem);
    return newItem;
  }
}
```

**CreateMyCustomDto**: A Data Transfer Object (DTO) used to validate incoming data when creating a new "MyCustom" entry.

```javascript
import { CreateMyCustomDto } from '../dto/create-my-custom.dto';

export interface MyCustomServiceInterface {
  findAll(): any[];
  create(createMyCustomDto: CreateMyCustomDto): any;
}
```

**MyCustomServiceInterface**: Defines the contracts the service must adhere to, ensuring compliance with best practices.

```javascript
import { CreateMyCustomDto } from '../dto/create-my-custom.dto';

export interface MyCustomServiceInterface {
  findAll(): any[];
  create(createMyCustomDto: CreateMyCustomDto): any;
}
```

**MyCustomModule Decorator**: A custom decorator that can be used to add metadata to dynamic modules (optional but useful for automation or dynamic loading scenarios).

<pre class="language-javascript"><code class="lang-javascript"><strong>import { SetMetadata } from '@nestjs/common';
</strong>
export const IS_MY_CUSTOM_MODULE = 'isMyCustomModule';

export const MyCustomModuleDecorator = () => SetMetadata(IS_MY_CUSTOM_MODULE, true);
</code></pre>

**MyCustomSubModule:** A submodule loader is also available. It searches within your module path, for example `src/modules/mycustommodule/`, to see if a `subModules` folder exists. It scans this folder looking for the following prerequisites:

The submodule decorator must be added: `@MYCUSTOMDECORATOR({})`.&#x20;

1. The custom decorator is defined within a service who extends BaseSubModulesLoader:

```javascript
import { Logger, Injectable, OnModuleInit } from '@nestjs/common';
import { BaseSubModulesLoader } from '../../../common/services/base-submodules-loader.service';
import { join } from 'path';

/**
 * DynamicSubModulesLoader Service
 * 
 * This service is responsible for dynamically loading NestJS modules from a specified directory.
 * It scans the directory for module folders, imports them, and verifies if they are marked as dynamic
 * using a custom decorator. Only modules marked as dynamic are loaded and returned for integration
 * into the NestJS application.
 */
@Injectable()
export class DynamicSubModulesLoader extends BaseSubModulesLoader {
  protected readonly logger = new Logger(this.constructor.name);
  protected metadataKey = 'MYCUSTOMDECORATOR';
  protected targetDirectory = join(__dirname, 'MY_PATH_TO_THE_SUBMODULE_DIRECTORY');
}
```

```javascript
import { Module, OnModuleInit } from '@nestjs/common';

// Decorators
import { MYCUSTOMDECORATOR } from 'MY_PATH_TO_THE_SUBMODULE_DIRECTORY';
// Database
import { User } from './models/user.model'; // Path to the User model

@MYCUSTOMDECORATOR({})
@Module({
    imports: [],
})
// The UserModule encapsulates all functionality related to user, 
// such as routing, business logic, and database operations.
export class UserModule implements OnModuleInit{
    onModuleInit() {
        console.debug('[DynamicModule]:[Sub]:[ UserModule ] -> initialisé');
    }
}
```

2. The submodule file must end with `.module.ts`.

The submodule functions as a fully independent module and can implement the same tools as a parent module. However, its loading depends on the parent module.
