Migration guide

This article provides a set of guidelines for migrating from 5 to the latest 6 version. Even though we tried to reduce a number of breaking changes, the API had to be modified in a few places in order to simplify its usage.

Middleware

Based on this topic, the middleware API has been changed in order to make it more straightforward for people who come from different Node libraries and also to reduce the number of confusions that arose from the previous API.

  1. @@filename()
  2. // Before
  3. @Injectable()
  4. export class LoggerMiddleware implements NestMiddleware {
  5. resolve(...args: any[]): MiddlewareFunction {
  6. return (req: Request, res: Response, next: Function) => {
  7. console.log('Request...');
  8. next();
  9. };
  10. }
  11. }
  12. // After
  13. @Injectable()
  14. export class LoggerMiddleware implements NestMiddleware {
  15. use(req: Request, res: Response, next: Function) {
  16. console.log('Request...');
  17. next();
  18. }
  19. }
  20. @@switch
  21. @Injectable()
  22. export class LoggerMiddleware {
  23. resolve(...args) {
  24. return (req, res, next) => {
  25. console.log('Request...');
  26. next();
  27. };
  28. }
  29. }
  30. // After
  31. @Injectable()
  32. export class LoggerMiddleware {
  33. use(req, res, next) {
  34. console.log('Request...');
  35. next();
  36. }
  37. }

Consequently, the with() method of the MiddlewareConsumer won’t work anymore (is fully useless). If you want to pass options to the middleware class, use a custom provider or check more examples here.

Interceptors

The interceptors API has also been simplified. In addition, the change was required due to this issue which was reported by the community.

  1. @@filename()
  2. // Before
  3. @Injectable()
  4. export class TransformInterceptor implements NestInterceptor {
  5. intercept(
  6. context: ExecutionContext,
  7. call$: Observable<T>,
  8. ): Observable<Response<T>> {
  9. return call$.pipe(map(data => ({ data })));
  10. }
  11. }
  12. // After
  13. @Injectable()
  14. export class TransformInterceptor implements NestInterceptor {
  15. intercept(
  16. context: ExecutionContext,
  17. next: CallHandler,
  18. ): Observable<Response<T>> {
  19. return next
  20. .handle()
  21. .pipe(map(data => ({ data })));
  22. }
  23. }
  24. @@switch
  25. // Before
  26. @Injectable()
  27. export class TransformInterceptor {
  28. intercept(context, next) {
  29. return call$.pipe(map(data => ({ data })));
  30. }
  31. }
  32. // After
  33. @Injectable()
  34. export class TransformInterceptor {
  35. intercept(context, next) {
  36. return next
  37. .handle()
  38. .pipe(map(data => ({ data })));
  39. }
  40. }

info Hint The CallHandler interface is exported from the @nestjs/common package.

Please note that your interceptors will now run in the correct order - they will follow a simple request processing pipeline, being executed from global to concrete once the request wants to hit an end-handler, and then (in response pipeline), they will be executed from specific to global ones (if you attach some asynchronous/mapping logic inside them).

Platforms

So far, even if you were not using an HTTP server, you had to install the express library internally (as a dependency of the @nestjs/core package). Since a new major release, Nest will no longer ship these packages upfront. Each platform has been extracted into an individual package, respectively @nestjs/platform-express, @nestjs/platform-fastify, @nestjs/platform-ws, and @nestjs/platform-socket.io. Assuming that your application was using both express and socket.io, you only have to install the corresponding platforms:

  1. $ npm i @nestjs/platform-express @nestjs/platform-socket.io

Every existing adapter (for example, FastifyAdapter) is now being served from the dedicated platform package.

  • FastifyAdapter - @nestjs/platform-fastify
  • ExpressAdapter - @nestjs/platform-express
  • WsAdapter - @nestjs/platform-ws
  • IoAdapter - @nestjs/platform-socket.io

Also, FileInterceptor (and other multer related interceptors) are now exported from @nestjs/platform-express (because multer library is not compatible with fastify).

Metadata reflection

The @ReflectMetadata() decorator has been deprecated and will be removed in the next major release (for now it will only display a warning). Use the @SetMetadata() decorator instead.

GraphQL

The subscriptions mechanism has been changed. Check this chapter for more details. Additionally, @nestjs/graphql package was heavily relying on @ReflectMetadata() (which has been deprecated) so it’s required to update the package itself as well.

Express instance

We no longer support passing express instance as a second argument of the NestFactory.create() method. In order to pluck underlying HTTP adapter, use techniques described here. Also, you can pass ExpressAdapter instead (simply pass your express instance as a constructor parameter new ExpressAdapter(express)).

  1. // Before (no longer supported)
  2. const server = express();
  3. const app = await NestFactory.create(ApplicationModule, server);
  4. // After (potential solution)
  5. const server = express();
  6. const app = await NestFactory.create(
  7. ApplicationModule,
  8. new ExpressAdapter(server),
  9. );

Deprecations

All deprecations (from 4 to 5 version) have been finally removed.

TypeScript

Nest 6 supports the latest major release of TypeScript (3.0.0).