In this post, we will understand how to use Global Modules in NestJS.

In an earlier post, we looked at sharing NestJS Services between modules. However, in that post we relied on the normal approach of exporting and importing providers to share them between different modules. While such an approach is usually preferred, it also leads to a bunch of boilerplate code to setup the imports.

What if you wish to have certain modules available globally in your application context?

This is where global modules come into the picture and we will be seeing those in action in this post.

If you are unfamiliar with the concept of modules in NestJS, please refer to my detailed post on NestJS Modules.

1 – Global Modules in NestJS

If there is a requirement to use the same module in several other modules, it might be a good idea to use Global Modules. Otherwise, it becomes quite tedious to import the same module everywhere by using imports array.

info

INFO

NestJS borrows many concepts from Angular. However, unlike Angular where providers are registered in global scope, NestJS scopes the providers to the module scope. A Module’s providers can only be used after importing the module itself.

Global Modules help bypass this rule.

You might wonder why every module should not be declared global. Well, in general, it is not a good practice. If we keep doing so, over time it will become next to impossible for us to figure out the dependency matrix of our application. In other words, it becomes tough to keep track of module dependencies. In the end, it can turn into a maintenance nightmare.

Due to this reason, we should use Global Modules strategically. Basically, classes like helpers or utilities and database configuration classes are good candidates for Global Modules.

2 – Declaring a Module as Global

Let’s take the example of our LoggingModule we saw in our post about sharing NestJS services.

It is quite possible that we use this module across many other modules in our application. Therefore, we can define this module as Global.

To do so, we simply annotate our Module class with @Global decorator.

import { Global, Module } from "@nestjs/common";
import { LoggingService } from "./logging.service";

@Global()
@Module({
    providers: [LoggingService],
    exports: [LoggingService],
})
export class LoggingModule {}

The @Global decorator makes the module’s scope as global. In other words, it will be available throughout the application context.

3 – Registering the Global Module

Even though we declare a module as global by using the @Global decorator, we still need to register the module. In the case of non-global modules, we basically import it in another module where we wish to use the module’s services.

However, we can register the global module in the root module. By doing so, we have no need to import it anywhere else.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { ABCController } from './abc.controller';
import { AppService } from './app.service';
import { BooksService } from './books/books.service';
import { BooksModule } from './books/books.module';
import { LoggingModule } from './logging/logging.module';

@Module({
  imports: [BooksModule, LoggingModule],
  controllers: [AppController, ABCController],
  providers: [AppService, BooksService],
})
export class AppModule {}

As you can see, we import the LoggingModule in the app.module.ts.

Now, we can use it in the BookModule directly as below:

import { Controller, Get, Body, HttpCode, Post} from "@nestjs/common";
import { LoggingService } from "src/logging/logging.service";
import { Book } from "./book.interface";
import { BooksService } from "./books.service";


@Controller('books')
export class BookController {

    constructor(private booksService: BooksService, private loggingService: LoggingService) {}

    @Get()
    @HttpCode(200)
    async findAll(): Promise<Book[]> {
        this.loggingService.logToConsole("Fetch All Request Received")
        return this.booksService.findAll()
    }

    @Post()
    @HttpCode(201)
    async create(@Body() book: Book){
        this.loggingService.logToConsole("Create New Book Request Received: " + book)
        this.booksService.create(book);
    }

}

Here’s the BookModule definition.

import { Module } from "@nestjs/common";
import { BookController } from "./book.controller";
import { BooksService } from "./books.service";


@Module({
    controllers: [BookController],
    providers: [BooksService]
})
export class BooksModule {

}

As you can see, we don’t need to import the LoggingModule explicitly over here. If we start the application, it will work as expected.

Conclusion

With this, we have successfully seen how to use Global Modules in NestJS.

Hope this post was useful. If you have any comments or queries, please feel free to mention in the comments section below.


NestJS is a fundamental pillar in my Cloud & Backend learning path. To know more, don’t forget to subscribe to the Progressive Coder newsletter.

Also, say ‘Hi’ on Twitter for more real-time updates on what’s happening at Progressive Coder

Categories: BlogNestJS

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *