2

How to Create Modules in NestJS: Step By Step Guide

 2 months ago
source link: https://blog.bitsrc.io/how-to-create-modules-in-nestjs-step-by-step-guide-943d0f414e13
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to Create Modules in NestJS: Step By Step Guide

What the article is going to cover

What is a module in NestJS?

A module encapsulates a closely related set of capabilities. — NestJS Docs

A Module lets you group a bunch of Services and Controllers to organize our code better, usually they focus on one aspect of the desired functionality.

For example, We can have a separate module for each of those responsibilities:
Logging, Data access layer (DAL), Feature Flag, Cache, and more.

1*wBCaCf4ezZuirTWQa0cGnw.png

Graph created with excalidraw

A module can expose its services to be consumed by other modules,
For example, a logging module will expose aLoggingService to use in logging across the app.

A module can also import other modules that it relies on (the same logic mentioned above but in the perspective of the “App Module”.

What are we building?

In this tutorial, We will take the Redis package and create a module for it,
We go from creating the simplest module to learning about dynamic modules and module life-cycle, module configurations, and global modules.

Creating A Simple module & Lifecycle Events

In this part, we will create a basic module that connects to our local Redis and exposes the client to be used by the app module.

Let’s create a new nest project

nest new redis-nestjs-module

Then, We will install the Redis package

npm i redis --save
npm i redis-memory-server -D

In the src folder we will remove all files, and start from the beginning

First, We will create redis.client.service.ts

lines 7–13 — We create getter and setter for our Redis client
lines 17–19 — We create an instance for our Redis client
lines 21–27 — NestJS allows us to add functionality between its life cycle,
onModuleInit — When our module is initializing —In our case, We create a connection to our Redis server.
onApplicationShutdown — When the app is about to be closed after all the client connections closed — In our case disconnect from our Redis server,
This is important, We don’t want to leave dangling connections,
Because it makes it hard to exit gracefully and it leads to “creative ways” to exit the app.

Read more about NestJS life cycle — here

Next, We will create redis.module.ts

providers — what services do we want to be initialized/used within our module — in our case, we want RedisClientService to be initialized
exports — what services do we want to be consumed by other modules, in our case — the RedisClientService

Next, we are going to create a test for our module,
Instead of unit tests, we can use integration tests here.

The functions in our module are tiny that in real life you would skip the unit test for them,
By doing the integration test — We can check that the entire module work as intended with even more confidence (than the usual unit tests)

In the test — We are going to create a module that will consume our Redis module, and test that the RedisClientService can connect to the Redis server.

Lines 9–16 — We create a module that consumes the Redis module that we created, and wait for the module to be initialized.
Lines 18–24 — We test that the Redis client is connected to the Redis server.
Lines 26–28 — We close the app.

Configuration for the test, setup, and teardown:

globalSetup.ts — We create a Redis server for the test
globalTeardown.ts — We close the Redis server
jest-integration.json — The configuration for jest to run the test
package.json — The relevant scripts to run the tests / debug the tests.

You can run the test with:

npm run test

You can see everything We have done here in the following link
Release v1

Dynamic Module & Dynamic configurations

In the previous part, We created a module that connects to a Redis server with the default configuration (it connects to localhost on port 6379),
But what if we want to connect with a different port or a different host?

The Redis package seems to let you pass configuration to the createClient method, So how can we pass the configuration to our RedisClientService?

NestJs packages usually use dynamic modules with dynamic providers to get configurations and pass that configuration between its providers

Let’s modify our module to be a dynamic module, and get the configuration for the createClient method.

To create a dynamic module, You create a static a method that returns an object that implements the DynamicModule interface from the @nestjs/common .
In the previous version, the configuration of the providers, and exports were inside the @Module decorator but now it is part of the returned object.

In addition, We added a dynamic provider on lines 12–15, the provider holds the configuration that we get from the function and can be used in other providers in our module, we are going to use it in our RedisClientService .

We also created two new files config.ts and consts.ts

Next, We gonna update RedisClientService to use the provider that contains the configuration for the createClient method.

We use @Inject(CONFIG_OPTIONS) to use the configuration provider.

For us to check that these changes work,
Let’s create the Redis server on a different port than the default one (6379),
And make sure our TestingModule can connect to the Redis server after the port change.

You can also see the changes we reviewed here:
Comparing v1…v2

Next Phases

We didn’t create a production-grade module here, There is a lot more to improve here, and I am not intending to make it production ready.
But there are still a few problems here that you might encounter with your module, So let’s tackle them.

Global Module

1*HTLaulKYW10IYUKIa63Z5Q.png

Graph created with excalidraw

Let’s assume that you have multiple modules consumed by your app module, each of those modules needs to consume your RedisModule, and they all connect to the same Redis instance

It might look something like this

Instead of repeating it multiple times, We can register our module globally, and it will let us use our providers from anywhere in the app

You can see the changes here:
Comparing v2…v3

read more about global modules here

Check out the GitHub repo with the entire code:

Other articles of mine that might be of interest to you:

Go composable: Build apps faster like Lego

1*mutURvkHDCCgCzhHe-lC5Q.png

Bit is an open-source tool for building apps in a modular and collaborative way. Go composable to ship faster, more consistently, and easily scale.

Learn more

Build apps, pages, user-experiences and UIs as standalone components. Use them to compose new apps and experiences faster. Bring any framework and tool into your workflow. Share, reuse, and collaborate to build together.

Help your team with:

Micro-Frontends

Design Systems

Code-Sharing and reuse

Monorepos


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK