Lesson 26-NestJS Integration with Fastify

NestJS uses the Express framework by default. As previously mentioned, Nest also provides compatibility with other libraries, such as Fastify. Nest achieves this framework independence by implementing a framework adapter, whose primary function is to proxy middleware and handlers to the appropriate library-specific implementations.

Installing Fastify Plugin

First, ensure you have the NestJS CLI installed and have created a new project. Then, install the Fastify plugin:

npm install --save @nestjs/platform-fastify fastify

Configuring the NestJS Application to Use Fastify

In the main.ts file, modify the Nest application to use Fastify as the server platform.

Example Code (main.ts):

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // Configure Fastify server
  app.enableCors(); // Enable Cross-Origin Resource Sharing (CORS), configure as needed

  // Listen on port
  await app.listen(3000);
}
bootstrap();

Creating Controllers and Routes

Next, create a simple controller to demonstrate the use of Fastify.

Example Code (cats.controller.ts):

import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  async findAll(): Promise<string> {
    return 'This is a list of cats from Fastify server!';
  }
}

Ensure this controller is properly imported in your AppModule.

Using Fastify Features

Fastify offers unique features such as custom plugins and decorators. While NestJS’s integration with Fastify primarily focuses on the server layer, you can still use Fastify’s APIs directly to extend functionality in your NestJS application.

For example, you can add a Fastify plugin to handle logging or other specific requirements.

Example Code (Adding a Fastify Plugin in main.ts):

import { FastifyPluginAsync } from 'fastify';

const fastifyPlugin: FastifyPluginAsync = async (fastify, options, done) => {
  fastify.addHook('onRequest', (request, reply, done) => {
    console.log(`Request received on ${request.url}`);
    done();
  });
  done();
};

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  app.register(fastifyPlugin); // Register custom Fastify plugin

  await app.listen(3000);
}
bootstrap();

Using Fastify Middleware

Fastify provides a powerful middleware system for handling requests and responses. You can leverage these middleware to enhance the functionality of your NestJS application.

Example Code (main.ts):

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // Add Fastify middleware
  app.use((request, reply, done) => {
    console.log(`Request received on ${request.url}`);
    done();
  });

  // Listen on port
  await app.listen(3000);
}
bootstrap();

Using Fastify Custom Plugins

Fastify allows you to register custom plugins to extend its functionality. These plugins can handle various tasks, such as logging or authentication.

Example Code (logger-plugin.ts):

import { FastifyPluginAsync } from 'fastify';

const loggerPlugin: FastifyPluginAsync = async (fastify, options, done) => {
  fastify.addHook('onRequest', (request, reply, done) => {
    console.log(`Request received on ${request.url}`);
    done();
  });
  done();
};

export default loggerPlugin;

Registering the Plugin (main.ts):

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import loggerPlugin from './logger-plugin';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // Register custom plugin
  app.register(loggerPlugin);

  // Listen on port
  await app.listen(3000);
}
bootstrap();

Performance Optimization

Fastify is known for its high performance, and you can take additional steps to further optimize your NestJS application’s performance.

  • Using Caching: For frequently accessed data, consider implementing caching to reduce database queries.
  • Asynchronous Processing: For time-consuming operations, use asynchronous processing to avoid blocking the main thread.
  • Reducing Unnecessary Computations: Ensure your business logic is as concise and efficient as possible, avoiding unnecessary computations.

Example Code (cats.service.ts):

import { Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager';

@Injectable()
export class CatsService {
  private cache: Cache;

  constructor(private readonly cacheManager: CacheManager) {
    this.cache = cacheManager.getCache();
  }

  async findAll(): Promise<string> {
    let cats = await this.cache.get('cats');
    if (!cats) {
      cats = 'This is a list of cats from Fastify server!';
      await this.cache.set('cats', cats, { ttl: 60 }); // Cache for 60 seconds
    }
    return cats;
  }
}
Share your love