API with NestJS #89. Replacing Express with Fastify (2024)

This entry is part 89 of 138 in the API with NestJS

By default, NestJS uses Express under the hood. Moreover, since Express is very popular, NestJS can choose from a broad set of compatible third-party solutions.

A significant advantage of NestJS is that it is framework-independent. Instead of using Express, we can use an adapter using another library with a similar request/response pipeline. The most popular implementation besides Express is the Fastify adapter.

Check out this repository to see the full code from this article.

Introducing Fastify

The main selling point of Fastify isperformance. We can find various comparisons on the web that prove that Fastify handles HTTP requests faster than Express.

However, there is a big chance that Express is not the bottleneck in your application. Instead, optimizing how we use our database and caching can yield great results.

If you want to know more about caching with NestJS, check out the following articles:

Using Fastify with NestJS

At first glance, it’s very straightforward to start using Fastify with NestJS. To do that, we only need to modify our main.ts file.

1

npm install @nestjs/platform-fastify

main.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import { NestFactory } from '@nestjs/core';

import { AppModule } from './app.module';

import {

FastifyAdapter,

NestFastifyApplication,

} from '@nestjs/platform-fastify';

import { ConfigService } from '@nestjs/config';

async function bootstrap() {

const app = await NestFactory.create<NestFastifyApplication>(

AppModule,

new FastifyAdapter(),

);

const configService = app.get(ConfigService);

await app.listen(configService.get('PORT'));

}

bootstrap();

When we do the above, NestJS starts using Fastify as its HTTP provider, and we don’t need to provide any additional configuration.

However, one of the biggest strengths of Express is its wide selection of compatible libraries. When using Fastify, we must ensure that the packages we use are compatible or use alternatives developed with Fastify in mind.

We also need to remember that since Express is the default solution for NestJS, all of the libraries maintained by the NestJS team are usually developed with Express in mind. Therefore, if we decide to go with Fastify, we must brace ourselves to deal with some incompatibilities.

Things to watch out for when switching to Fastify

Modifying our main.ts file is enough to start using Fastify. Although that’s the case, let’s go deeper and investigate some real-life scenarios to see what it’s like using Fastify.

In the third part of this series, we’ve implemented authentication using bcrypt, Passport, JWT, and cookies. Since many projects include some authentication, it is a good starting point to learn how to use Fastify with NestJS.

Accessing the request and response objects

When using Express, we can easily access the request and response object using the correct decorators.

categories.controller.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

import {

Controller,

Get,

UseInterceptors,

ClassSerializerInterceptor,

Req,

Res,

} from '@nestjs/common';

import CategoriesService from './categories.service';

import express from 'express';

@Controller('categories')

@UseInterceptors(ClassSerializerInterceptor)

export default class CategoriesController {

constructor(private readonly categoriesService: CategoriesService) {}

@Get()

async getAllCategories(

@Req() request: express.Request,

@Res() response: express.Response,

) {

console.log(`${request.method} ${request.url}`); // GET /categories

const categories = await this.categoriesService.getAllCategories();

response.send(categories);

}

// ...

}

When we use Fastify, we need to use different interfaces for the above objects.

categories.controller.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

import {

Controller,

Get,

UseInterceptors,

ClassSerializerInterceptor,

Req,

Res,

} from '@nestjs/common';

import CategoriesService from './categories.service';

import { FastifyReply, FastifyRequest } from 'fastify';

@Controller('categories')

@UseInterceptors(ClassSerializerInterceptor)

export default class CategoriesController {

constructor(private readonly categoriesService: CategoriesService) {}

@Get()

async getAllCategories(

@Req() request: FastifyRequest,

@Res() response: FastifyReply,

) {

console.log(`${request.method} ${request.url}`); // GET /categories

const categories = await this.categoriesService.getAllCategories();

response.send(categories);

}

// ...

}

While in the above example, Express and Fastify work the same, this is not always the case. For example, to set a header in the response, we need to use the response.header() function instead of response.setHeader().

authentication.controller.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

import {

Req,

Controller,

HttpCode,

Post,

UseGuards,

ClassSerializerInterceptor,

UseInterceptors,

Res,

} from '@nestjs/common';

import { AuthenticationService } from './authentication.service';

import RequestWithUser from './requestWithUser.interface';

import { LocalAuthenticationGuard } from './localAuthentication.guard';

import { FastifyReply } from 'fastify';

@Controller('authentication')

@UseInterceptors(ClassSerializerInterceptor)

export class AuthenticationController {

constructor(private readonly authenticationService: AuthenticationService) {}

@HttpCode(200)

@UseGuards(LocalAuthenticationGuard)

@Post('log-in')

async logIn(

@Req() request: RequestWithUser,

@Res({ passthrough: true }) response: FastifyReply,

) {

const { user } = request;

const cookie = this.authenticationService.getCookieWithJwtToken(user.id);

response.header('Set-Cookie', cookie);

return user;

}

// ...

}

Thanks to using passthrough: true we can return the data from the above method and let NestJS send the data. Without that, we would need to call the response.send() method instead.

Working with cookies

The cookie-parser library is a very popular middleware ready to use with Express. However, when using Fastify, we need to find an alternative.

1

npm install @fastify/cookie

Fortunately, the @fastify/cookie library is straightforward. For our application to support cookies, we need to modify our main.ts file and call the app.register method.

main.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

import { NestFactory } from '@nestjs/core';

import { AppModule } from './app.module';

import {

FastifyAdapter,

NestFastifyApplication,

} from '@nestjs/platform-fastify';

import { ConfigService } from '@nestjs/config';

import cookie from '@fastify/cookie';

async function bootstrap() {

const app = await NestFactory.create<NestFastifyApplication>(

AppModule,

new FastifyAdapter(),

);

await app.register(cookie);

const configService = app.get(ConfigService);

await app.listen(configService.get('PORT'));

}

bootstrap();

Passport

In this series, we’ve used the Passport library to avoid implementing all aspects of authentication manually. Sadly, the @nestjs/passport library does not support Fastify officially.

There is the @fastify/passport package, but it’s not very popular. Unfortunately, it integrates with Passport differently, and guards built into NestJS might not work out of the box with it.

Thankfully, @nestjs/passport works fine with Passport as long as we use simple JWT-based authentication.

authentication.controller.ts

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import { ExtractJwt, Strategy } from 'passport-jwt';

import { PassportStrategy } from '@nestjs/passport';

import { Injectable } from '@nestjs/common';

import { ConfigService } from '@nestjs/config';

import { UsersService } from '../users/users.service';

import TokenPayload from './tokenPayload.interface';

@Injectable()

export class JwtStrategy extends PassportStrategy(Strategy) {

constructor(

private readonly configService: ConfigService,

private readonly userService: UsersService,

) {

super({

jwtFromRequest: ExtractJwt.fromExtractors([

(request: { cookies: Record<string, string> }) => {

return request?.cookies?.Authentication;

},

]),

secretOrKey: configService.get('JWT_SECRET'),

});

}

async validate(payload: TokenPayload) {

return this.userService.getById(payload.userId);

}

}

We can access request?.cookies?.Authentication thanks to using the @fastify/cookie library.

Please notice that above we use request: { cookies: Record<string, string> } instead of request: FastifyRequest. This is because using the latter would cause TypeScript to complain that FastifyRequest is incompatible with express.Request.

While JWT-based authentication works fine, we might encounter issues when implementing OAuth. Thankfully, the official Discord channel of NestJS is a great place to get help with such problems. For example, Jay McDoniel, who is a part of the core NestJS team, suggests adding the following snippet to our main.ts file if we want to make @nestjs/passport work with OAuth and Fastify:

1

2

3

4

5

6

7

8

9

10

11

const fastifyInstance: FastifyInstance = app.getHttpAdapter().getInstance()

fastifyInstance

.addHook('onRequest', async (req, res) => {

req.socket['encrypted'] = process.env.NODE_ENV === 'production'

})

.decorateReply('setHeader', function (name: string, value: unknown) {

this.header(name, value)

})

.decorateReply('end', function () {

this.send('')

})

In the above code we try to make Fastify more compatible with how the request and response objects work in Express.

Summary

In this article, we’ve replaced Express with Fastify and achieved a fully-working application that includes authentication. While configuring NestJS to use Fastify is very simple, working with Fastify might not be that convenient. When switching to Fastify, we might increase the performance of our application, but we need to be aware of the disadvantages.

API with NestJS #89. Replacing Express with Fastify (1)

There is a big community behind Express, and it shows. If your application requires top-notch performance, it’s worth giving Fastify a try.

Series Navigation<< API with NestJS #88. Testing a project with raw SQL using integration testsAPI with NestJS #90. Using various types of SQL joins >>

As an expert in web development and the NestJS framework, I have extensive knowledge of the topics discussed in the provided article series. My expertise spans various aspects of building APIs with NestJS, including controllers, routing, module structure, database setup, authentication, error handling, data validation, serialization, dependency injection, testing, file uploads, microservices, GraphQL, database relationships, caching, and many more.

The article you've shared is the 89th entry in a series that specifically focuses on using Fastify as the HTTP provider in NestJS instead of the default Express. The series covers a wide range of topics, from basic API setup to advanced topics such as working with databases (PostgreSQL, MongoDB), implementing authentication strategies, optimizing performance, using different libraries and frameworks, and deploying applications to cloud services like AWS.

In the 89th entry, the author introduces Fastify as a high-performance alternative to Express and walks through the process of integrating it into a NestJS application. The article highlights key points to consider when switching from Express to Fastify, such as differences in handling request and response objects, and the need for compatibility with libraries used in the NestJS ecosystem.

Some specific concepts and topics covered in the provided article include:

  1. Fastify Integration with NestJS:

    • Switching from Express to Fastify in the main.ts file.
    • Using @nestjs/platform-fastify and @nestjs/core to create a NestFastifyApplication.
  2. Handling Request and Response Objects:

    • Adapting code to use FastifyRequest and FastifyReply instead of Express's Request and Response.
    • Making adjustments in controllers to work seamlessly with Fastify.
  3. Working with Cookies:

    • Introducing the @fastify/cookie library to support cookies in a Fastify-based NestJS application.
    • Modifying the main.ts file to register the cookie plugin.
  4. Authentication with Passport:

    • Discussing challenges when using Passport with Fastify.
    • Demonstrating how to use JWT-based authentication with Fastify and @nestjs/passport.
  5. OAuth and NestJS Passport:

    • Addressing potential issues with OAuth authentication in a Fastify environment.
    • Adding code snippets to enhance compatibility with OAuth and Fastify.
  6. Performance Considerations:

    • Highlighting the main selling point of Fastify as performance.
    • Discussing the need to evaluate whether the performance gain justifies the potential downsides of using Fastify.

In summary, the article serves as a practical guide for developers looking to leverage the performance benefits of Fastify in a NestJS application while addressing common challenges and considerations associated with the transition from Express.

API with NestJS #89. Replacing Express with Fastify (2024)

FAQs

Which is better Nestjs Express or Nestjs fastify? ›

Fastify provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much faster than Express, achieving almost two times better benchmarks results.

Does Fastify replace Express? ›

Fastify is a new framework that has the same functionality as Express and Hapi, while boasting that it has faster speed, a better developer experience and more flexibility.

Why is Fastify better than Express? ›

In benchmarks, Fastify has shown to be significantly faster than Express in terms of request throughput and response time. However, it's important to note that the performance of your server will depend on a variety of factors, including your hardware, network, and the complexity of your application.

Why is Fastify not popular? ›

The setup process is relatively complex. Its typing system seems incomplete; my IDE displays errors even when I use code directly from the official documentation. Integrating Fastify with a separate Node. js HTTP server is not as straightforward as with Express.

Is fastify worth learning? ›

However, if you're looking for a faster, more efficient alternative with built-in validation and serialization, Fastify is an excellent option. It's well-suited for developers who prioritize performance, a modern async/await-based approach, and a structured plugin system.

Why use NestJS instead of Express? ›

While ExpressJS is known for its flexibility, the absence of a CLI means developers may need to manage more code-related tasks directly. NestJS: NestJS distinguishes itself by incorporating a powerful CLI (command-line interface) that significantly enhances productivity.

What is the alternative to fastify Express? ›

Top Alternatives of ExpressJS
  • SailsJS. Sails is a robust, flexible, high-performance MVC framework for NodeJS. ...
  • NestJs. NestJS is a full-stack JavaScript framework for building efficient and scalable server-side applications. ...
  • Fastify. ...
  • FeatherJS. ...
  • NuxtJS. ...
  • Koa. ...
  • EmberJS. ...
  • BackboneJS.
Jun 3, 2024

How many requests can fastify handle? ›

A benchmark made by Fastify, shows that Express. js— a minimal and flexible Node. js web application framework with a robust set of features for web and mobile— can handle approx 15,000 requests per second and the basic HTTP module, 70K requests per second. This is very fast.

Is Fastify worth it on Reddit? ›

Fastify has a more modern ecosystem of plugins, but it might not be important if you've found your favorite set of express tools. As usual, it depends. If something bothers you are with express, give fastify a try to see if it works better. A surprisingly unbiased and fair reply!

What are the disadvantages of fastify? ›

Disadvantages of Fastify

This can result in limited availability of community-developed plugins, extensions, and community-driven support resources. Organizations may find it challenging to find extensive documentation, pre-built solutions, or ready-made integrations for specific use cases.

Is fastify a framework or library? ›

Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town.

Should you use Express with Node? ›

You should choose JavaScript runtime environment when you need a server-side runtime environment for JavaScript. On the other hand, you can choose Express JS when you want to build web applications or APIs with a structured framework on top of Node JS.

What is better than NestJS? ›

Nestjs offers built-in support for TypeScript, dependency injection, and modular architecture, while Expressjs provides minimalism and flexibility. The choice depends on the specific requirements of the project.

Which companies use fastify? ›

List of companies using Fastify
CompanyCountryIndustry
Peter Park System GmbHGermanyIt Services And It Consulting
LRQA - sustainabilityGermanyBusiness Consulting And Services
PipedriveUnited StatesSoftware Development
Grupo BoticárioBrazilPersonal Care Product Manufacturing
8 more rows

Is fastify compatible with Express? ›

You can register an entire Express application and make it work with Fastify.

What are the benefits of fastify? ›

Fastify shines in scenarios where performance and speed are critical without compromising on the developer experience. It's particularly adept at handling: High-Throughput Applications: Fastify's efficient request handling mechanism makes it ideal for applications that require handling thousands of requests per second.

What is NestJS fastify? ›

Nest is a framework for building efficient, scalable Node. js server-side applications. It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Top Articles
Disconnect incoming VPN connection - Windows Client
Could RSA-2048 Be Cracked By 2025?
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Pearson Correlation Coefficient
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
Latest Posts
Article information

Author: Kelle Weber

Last Updated:

Views: 6085

Rating: 4.2 / 5 (73 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Kelle Weber

Birthday: 2000-08-05

Address: 6796 Juan Square, Markfort, MN 58988

Phone: +8215934114615

Job: Hospitality Director

Hobby: tabletop games, Foreign language learning, Leather crafting, Horseback riding, Swimming, Knapping, Handball

Introduction: My name is Kelle Weber, I am a magnificent, enchanting, fair, joyous, light, determined, joyous person who loves writing and wants to share my knowledge and understanding with you.