NestJSで、モジュールがグローバルのインターセプター、フィルター、ガードを回避する方法

NestJSアプリケーションを開発する際、特定のモジュール(例:SpecialModule)がグローバルのインターセプター(useGlobalInterceptors)、フィルター(useGlobalFilters)、およびガード(useGlobalGuards)を回避する必要がある場合があります。この記事では、NestJSでSpecialModuleを実現し、グローバルインターセプター、フィルター、ガードに手動でロジックを追加してSpecialModuleのルートをスキップする方法を紹介します。

ステップ1:SpecialModuleを作成する

まず、SpecialModuleを作成します。Nest CLIを使用するか、手動でモジュールファイルを作成します。

Terminal window
1
nest g module special

ステップ2:SpecialControllerとSpecialServiceを作成する

次に、SpecialModuleのためにコントローラーとサービスを作成します。

Terminal window
1
nest g controller special
2
nest g service special

special.controller.tsに簡単なルートを追加します:

1
import { Controller, Get } from "@nestjs/common";
2
import { SpecialService } from "./special.service";
3
4
@Controller("special")
5
export class SpecialController {
6
constructor(private readonly specialService: SpecialService) {}
7
8
@Get()
9
getSpecialData() {
10
return this.specialService.getSpecialData();
11
}
12
}

special.service.tsに簡単なメソッドを追加します:

1
import { Injectable } from "@nestjs/common";
2
3
@Injectable()
4
export class SpecialService {
5
getSpecialData() {
6
return { message: "Special data" };
7
}
8
}

ステップ3:AppModuleを修正してSpecialModuleを含める

AppModuleSpecialModuleを含めます:

1
import { Module } from "@nestjs/common";
2
import { SpecialModule } from "./special/special.module";
3
4
@Module({
5
imports: [SpecialModule],
6
controllers: [],
7
providers: [],
8
})
9
export class AppModule {}

ステップ4:グローバルインターセプター、フィルター、ガードを作成する

グローバルインターセプター、フィルター、ガードを作成し、SpecialModuleのルートをスキップするロジックを追加します。

グローバルインターセプターを作成する

1
import {
2
Injectable,
3
NestInterceptor,
4
ExecutionContext,
5
CallHandler,
6
} from "@nestjs/common";
7
import { Observable } from "rxjs";
8
import { tap } from "rxjs/operators";
9
10
@Injectable()
11
export class GlobalInterceptor implements NestInterceptor {
12
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
13
const controller = context.getClass();
14
const controllerName = controller.name;
15
16
// SpecialControllerに属しているかどうかをチェック
17
if (controllerName === "SpecialController") {
18
return next.handle();
19
}
20
21
// グローバルインターセプターのロジックを実行
22
return next
23
.handle()
24
.pipe
25
// ... ここにグローバルロジックを追加
26
();
27
}
28
}

グローバルフィルターを作成する

1
import {
2
ExceptionFilter,
3
Catch,
4
ArgumentsHost,
5
HttpException,
6
} from "@nestjs/common";
7
import { Request, Response } from "express";
8
9
@Catch(HttpException)
10
export class GlobalFilter implements ExceptionFilter {
11
catch(exception: HttpException, host: ArgumentsHost) {
12
const ctx = host.switchToHttp();
13
const request = ctx.getRequest<Request>();
14
const response = ctx.getResponse<Response>();
15
const status = exception.getStatus();
16
17
const controller = host.getArgByIndex(1).constructor.name;
18
19
// SpecialControllerに属しているかどうかをチェック
20
if (controller === "SpecialController") {
21
return response.status(exception.getStatus()).json({
22
statusCode: status,
23
message: exception.message,
24
});
25
}
26
27
// グローバルフィルターのロジックを実行
28
response.status(status).json({
29
statusCode: status,
30
timestamp: new Date().toISOString(),
31
path: request.url,
32
});
33
}
34
}

グローバルガードを作成する

1
import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
2
import { Observable } from "rxjs";
3
4
@Injectable()
5
export class GlobalGuard implements CanActivate {
6
canActivate(
7
context: ExecutionContext,
8
): boolean | Promise<boolean> | Observable<boolean> {
9
const controller = context.getClass();
10
const controllerName = controller.name;
11
12
// SpecialControllerに属しているかどうかをチェック
13
if (controllerName === "SpecialController") {
14
return true;
15
}
16
17
// グローバルガードのロジックを実行
18
// ... ここにグローバルロジックを追加
19
return true;
20
}
21
}

ステップ5:メインアプリケーションにグローバルインターセプター、フィルター、ガードを適用する

main.tsでグローバルインターセプター、フィルター、ガードを登録します:

1
import { NestFactory } from "@nestjs/core";
2
import { AppModule } from "./app.module";
3
import { GlobalInterceptor } from "./global.interceptor";
4
import { GlobalFilter } from "./global.filter";
5
import { GlobalGuard } from "./global.guard";
6
7
async function bootstrap() {
8
const app = await NestFactory.create(AppModule);
9
app.useGlobalInterceptors(new GlobalInterceptor());
10
app.useGlobalFilters(new GlobalFilter());
11
app.useGlobalGuards(new GlobalGuard());
12
await app.listen(3000);
13
}
14
bootstrap();

これらの変更により、SpecialModule内のSpecialControllerはグローバルインターセプター、フィルター、ガードの影響を受けません。他のルートは引き続きグローバルインターセプター、フィルター、ガードによって処理されます。

結論

上記の手順を通じて、特定の SpecialModule を作成し、グローバルインターセプター、フィルター、ガードにロジックを追加して SpecialModule のルートをスキップできるようにしました。この方法がNestJSプロジェクトで役立つことを願っています。