How to configure modules in a NestJS project
Tags: nestjs, backend, node, javascript
Published: 2024-01-14 01:20:04

NestJS has a defined structure on how to configure your modules. Whenever you misconfigure this step, then you tend to get a frustrating error like the one below:


![NestJS error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jncn687mao0ybvzf25bp.png)

In this article, I will run you through how I configured modules for my pet project to give you an insight into how everything works and help you overcome errors such as the above.

The gist of my project is that users can sign up for the app and view recipes: a database stores recipes and users.

Starting with I have defined an app.module.ts below:

```javascript
@Module({
 imports: [
   AuthModule,
   UsersModule,
   MongooseModule.forRoot(process.env.MONGODB_STORE_URI || 'mongodb://localhost/Meal'),
   RecipesModule
 ],
})
```



My app.module.js is the root module that Nest.js leverages to build the internal structure of the application, the modules, and the providers stemming from the modules and the relationships between them. I have defined them in the imports list because this is where we grab the providers from the modules needed in this module to build the application's internal structure. The modules include the ones I have defined: AuthModule, UsersModule, RecipesModule, and the 3rd-party module MongooseModule, which we use to establish a connection to the database.

Now, let's move on to one of the modules in the imports list, the recipe Module, to understand how to configure an individual module.

```javascript
@Module({
 imports: [MongooseModule.forFeature([{ name: Recipe.name, schema: RecipeSchema }])],
 controllers: [RecipeController],
 providers: [RecipeService, Recipe]
})
```

The imports, by definition, are the providers stemming from the modules we use in this module. We have a MongooseModule.forFeature here to register the Recipe Model.

We have a key for controllers. It, by definition, is for just the controllers used in this module.


Next, the providers: I have defined RecipeService and Recipe here. The reason is that providers, by definition, are those we want to share, at least across this module. I inject the recipe model into the Recipe service. And the Recipe Service is injected into my controller. Hence, they need to be part of the providers. 




```javascript
@Injectable()
export class RecipeService {
   constructor(@InjectModel(Recipe.name) private recipeModel: Model<Recipe>)
   { }
```


```javascript
@Controller('/api/v1')
export class RecipeController {
   constructor(private readonly recipeService: RecipeService
   ) { }
```


Now, let's move on to the Users module.

```javascript
@Module({
 imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
 providers: [UsersService, User],
 exports: [UsersService]
})
```


We have already discussed the reason for providers; they need to be used by just this module, UsersService and User. 
Interestingly, now we have a key for exports, which has UserService as an item in its list. The exports are the subset of the providers that should be available in other modules that import this module.
Let's review another module, AuthModule, to elaborate on why we have exports listed this way.


```javascript
 imports: [
   UsersModule,
   JwtModule.register({
     global: true,
     secret: process.env.JWT_SECRET || jwtConstants.secret,
     signOptions: { expiresIn: '60s' },
   }),
 ],
 providers: [AuthService],
 controllers: [AuthController]
```


If we look at the imports list, we have an item for the UsersModule. Further, going deeper into the AuthService:

```javascript
@Injectable()
export class AuthService {
 constructor(
   private usersService: UsersService,
   private jwtService: JwtService
 ) {}
```



We are injecting the usersService into the constructor.


I hope this article will help you configure your modules for your own NestJS projects; feel free to leave any comments in the form of feedback.


References
1: https://docs.nestjs.com/modules