高瀬博道の技術ブログ

高瀬博道の技術ブログです。

もう2023年になったので、今さらNestJSに入門しようと思う - その7

前回

takasehiromichiex.com

ミドルウェア

ミドルウェアは、ルートハンドラの前に呼び出されるメソッドです。

主に、リクエスト、レスポンスに干渉することができます。

Nestのミドルウェアは、デフォルトではExpressのミドルウェアと同等です。

では、ミドルウェアを作成してみましょう。

$ nest g middleware middleware/logger

以下のファイルが生成されます。

src/middleware/logger/logger.middleware.spec.ts
import { LoggerMiddleware } from './logger.middleware';

describe('LoggerMiddleware', () => {
  it('should be defined', () => {
    expect(new LoggerMiddleware()).toBeDefined();
  });
});
src/middleware/logger/logger.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    next();
  }
}

これを、ログを出力するように修正します。

src/middleware/logger/logger.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    console.log("Request...");
    next();
  }
}

モジュールへのミドルウェアの適用

@Module()デコレータにはミドルウェアの場所がないので、モジュールを少し調整する必要があります。

src/app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { LoggerMiddleware } from './middleware/logger/logger.middleware';

@Module({
  imports: [CatsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('cats');
  }
}

まず、NestModuleimplementsしています。

そして、configureをオーバーライドしています。

ルートハンドラの中で、/catsのパスに対してミドルウェアをセットアップしています。

この状態で、パスに/catsを含むAPIを呼び出すと、npm run start:devしているコンソール上に、Request...と表示されます。

さらに、パスだけでなく、メソッドも指定することができます。

src/app.module.ts
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { LoggerMiddleware } from './middleware/logger/logger.middleware';

@Module({
  imports: [CatsModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes({path: 'cats', method: RequestMethod.GET});
  }
}

これで、GETメソッドかつパスに/catsを含むAPIを呼んだ際にのみ、ログにRequest...と表示されるようになりました。

まとめ

ここまでで、

  • ミドルウェアの作成
  • ルートモジュールへのミドルウェアの適用

を行いました。

次回は、もう少しミドルウェアを掘り下げようと思います。

コード

今回のコードは、以下に格納しました。

github.com

takasehiromichiex.com