# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gruntsass.gitbook.io/template-api-nodejs/nodejs/premium-template-rest-api/dynamic-module/create-or-import-module.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
