Node.js Framework Series— 1.1. NestJS — Lifecycle events
NestJS manages an application’s and it’s all of elements’ lifecycle. It provides lifecycle hooks that gives visibility into key lifecycle events and the ability to run registered code on our module, injectable or controller when they occur. We can say that NestJS divides the overall lifecycle into three phases: initialising, running and terminating. According to this lifecycle, we can plan for appropriate initialisation of modules and services, manage active connections, and shutdown our application when it receives a termination signal. We can explain it with the following diagram that is taken from the NestJS documentation:
Lifecycle events are triggered during the application bootstrapping and shutdown.
· onModuleInit() : Called once the host module’s dependencies have been resolved.
· onApplicationBootstrap() : Called once all modules have been initialised, but before listening for connections.
· onModuleDestroy() : Called after a termination signal (e.g., SIGTERM) has been received.
· beforeApplicationShutdown() : Called after all onModuleDestroy() handlers have completed (Promises resolved or rejected). Once complete (Promises resolved or rejected), all existing connections will be closed (app.close() called).
· onApplicationShutdown(): Called after connections close (app.close() resolves.
onModuleDestroy, beforeApplicationShutdown and onApplicationShutdown are only triggered if you explicitly call app.close() or if the process receives a special system signal (such as SIGTERM) and you have correctly called enableShutdownHooks at application bootstrap.
Lifecycle events usage
Every lifecycle hook is represented by an interface. To register a lifecycle hook, implement the appropriate interface. For instance, as shown below:
app.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
@Injectable()
export class AppService implements OnModuleInit {
onModuleInit() {
console.log(`The module has been initialised.`);
}
getHello(): string {
return 'Hello World!';
}
}
When we run the app, we will see the app log as shown below:
$ npm run start
..
[Nest] 10824 - 10/14/2020, 12:37:49 [RoutesResolver] ProfileController {/profile}: +0ms
The module has been initialized.
[Nest] 10824 - 10/14/2020, 12:37:49 [NestApplication] Nest application successfully started +3ms
As you see above on the app log, lifecycle hooks are triggered on the appropriate events. For instance, in our example OnModuleInit event is triggered when the app.controller.ts initialised. Like this example, we can register all of the lifecycle events to any NestJS class (e.g., Controller, Provider/Service or Module).
Application shutdown
NestJS disabled to use shutdown hook listeners by default. Because they consume system resources. But this feature is often used with Kubernetes [1]to manage the container’s lifecycles on cloud systems. The onModuleDestroy(), beforeApplicationShutdown() and onApplicationShutdown() hooks are called in the terminating phase (in response to an explicit call to app.close() or upon receipt of system signals such as SIGTERM if opted-in).
Let’s have a look at the following example to see how we can use in our application:
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Starts listening for shutdown hooks
app.enableShutdownHooks();
await app.listen(3000);
}
bootstrap();
and we adds onApplicationShutdown hook to our service class as shown below:
app.service.class
import { Injectable, OnApplicationShutdown } from '@nestjs/common';@Injectable()
export class AppService implements OnApplicationShutdown {
onApplicationShutdown(signal: string) {
console.log('Application is shutdown.'); // e.g. "SIGINT"
console.log(signal); // e.g. "SIGINT"
}
getHello(): string {
return 'Hello World!';
}
}
Let’s run it by using $npm run start and kill the application (by using CTRL+C on MacOS) on the console:
[Nest] 11094 - 10/14/2020, 13:03:10 [NestApplication] Nest application successfully started +1ms^CApplication is shutdown.
SIGINT
As you see on the examples, to register lifecycle event hooks to our NestJS application is very simple.
Resources:
- Lifecycle events, 2020, available at https://docs.nestjs.com/fundamentals/lifecycle-events
- Kubertetes official website, 2020, available at https://kubernetes.io/