💡

NestJS + serverlessのアプリの一部にバッチ処理を入れる

2021/09/16に公開

NestJSで構築した、ServerlessFrameworkを使ってデプロイするようなアプリケーションについて、普通のエンドポイントと別にバッチ処理を動かしたいことがありました。
結論から言うとbatch処理用のhandlerを用意して

手法の比較

バッチ処理というキーワードだけだと

  1. NestJSのTask Scheculingを使う
  2. NestJSにAPIの口を普通に作って、APIを定期実行するLambdaを外で作る
  3. APIを定期実行するLambdaをserverlessで新しく用意する
  4. serverlessに新しいfunctionsの口を生やす

みたいな手法が自分にはぱっと思い浮かびます。これらの比較をします。
1. については、NestJSが常時起動している必要があります。ServerlessFrameworkだとLambdaで、リクエスト時に起動するので、この方法はできません。EC2の場合は可能です。
2. は定期実行の口の権限まわりの管理にややコストがかかると思います。
3. はありですが、4の方がより楽なので4がおすすめです。

やり方

まず最初にserverless.yamlにbatch用の口をはやします。

functions:
  index:
    handler: src/handler.handler
    events:
      - http:
          path: '/'
          method: any
  batch:
    handler: src/batch_handler.handler
    events:
      - schedule: rate(1 minute)

こんな感じで、APIGWは不要なのでeventsだけ作ります。rate(1 minute)は1分後です。
次にbatch用のhandlerを作ります。叩きたいバッチをserviceの中に書いておいて、以下のようなhandlerを作ります。

import { NestFactory, Reflector } from '@nestjs/core';
import { Context, Handler } from 'aws-lambda';
import { TargetModule } from './hogehoge.module';
import { TargetSerice } from './hogehoge.service';

export const handler: Handler = async (event: any, context: Context) => {
  const app = await NestFactory.create(TargetModule);
  const service = await app.resolve(TargetSerice);
  await service.batchCalcHighScoreSection();
};

handler().catch(console.error)

これでバッチが動きます。やったね。

Discussion