🌊

【Express】Prismaとnode-cronを利用したバッチ処理の解説

2023/08/19に公開

Prismaとnode-cronを利用し、バッチでAPIを叩くコードを解説します。

Cron

まず、cronとは何かについて軽く触れておきます。
UNIX系OSに実装されているデーモンの一つで、設定したスケジュールで指定したプログラムを定期実行してくれる機能です。
cronが利用されている機能をいくつか挙げます。

  • バックアップ
    データのバックアップは重要かつ面倒な作業なので、cronを利用して定期実行することは一般的な使用例です。

  • メール送信
    毎週のニュースレターなどの定期的な処理はcronを利用して行われます。

  • バッチ処理
    DBの集計や大量データの処理などの、ユーザーから非同期で行われるバッチ処理はcronが利用されます。

実装

前提

schema.prismaでUserモデルとPostモデルを定義し、初期データがinsertされている状態です。

// schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model User {
  id  Int@id @default(autoincrement())
  userName String @unique
  email String @unique
  isPassword String
  role Role @default(USER)
  posts Post[]
}

enum Role {
  USER
  ADMIN
}

model Post {
  id Int @id @default(autoincrement())
  title String
  content String
  userId Int
  user User @relation(fields: [userId], references: [id])
}

node-cronインストール

nodeアプリケーションでcronを実装する為のライブラリであるndoe-cronをyarn経由でインストールします。

yarn add @types/node-cron

cronPostsメソッド

実行時点から「20秒間隔」のスケジューラを設定して、Postモデルを取得するcronPostsメソッドを実装します。
バッチで出力されるログを追いやすくするために、consoleでの出力とします。

import cron from "node-cron";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async cronPosts(_req: Request, _res: Response): Promise<void> {
  cron.schedule("*/20 * * * * *", async () => {
    const posts = await prisma.post.findMany();
    console.log(posts);
  });
}
  • 一度目のログ
[nodemon] starting `ts-node server.ts`
dev server running at: http://localhost:3000/
[
  { id: 1, title: 'title01', content: 'content01', userId: 1 },
  { id: 2, title: 'title02', content: 'content02', userId: 1 }
]
  • 20秒後のログ
[nodemon] starting `ts-node server.ts`
dev server running at: http://localhost:3000/
[
  { id: 1, title: 'title01', content: 'content01', userId: 1 },
  { id: 2, title: 'title02', content: 'content02', userId: 1 }
]
[
  { id: 1, title: 'title01', content: 'content01', userId: 1 },
  { id: 2, title: 'title02', content: 'content02', userId: 1 }
]

20秒おきにprismaのPostモデル全件取得が実行されている事が確認できます。
処理を停止しなければ、20秒おきにメソッドの実行が続いていきます。

cron形式

*/20 * * * * *のような定期実行の指示をcron形式と言ったりします。
20秒間以外のパターンも色々とあります。

  • 1時間おき
    0 * * * *
  • 1日おき
    0 0 */1 * *
  • 1週間おき
    0 0 * * 0
  • 10日おき
    0 0 */10 * *

Discussion