【Node.js】PostgreSQLデータベースの更新をリッスンする

こんにちは、フリーランスエンジニアの太田雅昭です。

PostgreSQLをリッスンするのに必要なこと

以下の手順が必要です。

  • DBにFunctionを登録
  • DBにTriggerを登録
  • Subscriberにリスナーを登録、接続、リッスン

順を追ってみていきます。

Functionを登録

まずPostgreSQLにFunctionを登録する必要があります。以下はプレーンなsqlです。

CREATE OR REPLACE FUNCTION my_function_name()
RETURNS TRIGGER AS $$
BEGIN
    PERFORM pg_notify('my_channel_name', row_to_json(NEW)::text);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Prismaだと以下になります。

await this.prisma.$executeRaw(Prisma.sql`
    CREATE OR REPLACE FUNCTION ${Prisma.raw(functionName)}()
    RETURNS TRIGGER AS $$
    BEGIN
        PERFORM pg_notify('${Prisma.raw(
            channelName,
        )}', row_to_json(NEW)::text);
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
`);

Triggerを登録

まずはsql文です。

CREATE OR REPLACE TRIGGER my_trigger_name
AFTER UPDATE ON "my_table_name"
FOR EACH ROW EXECUTE FUNCTION my_function_name();

prismaだと以下です。

await this.prisma.$executeRaw(Prisma.sql`
    CREATE OR REPLACE TRIGGER ${Prisma.raw(triggerName)}
    AFTER UPDATE ON "${Prisma.raw(tableName)}"
    FOR EACH ROW EXECUTE FUNCTION ${Prisma.raw(functionName)}();
`);

Subscriberを作成

pg-listenを使って、Subscriberを作っていきます。長く更新されていないライブラリですが、TypeScriptでばっちり使えるのはありがたいですね。

yarn add pg-listen pg

まずは初期化します。

import createSubscriber from 'pg-listen';
const subscriber = createAubscriber({
    connectionString: process.env['DATABASE_URI'], // postgres://postgres:postgrespassword@localhost:5432/xxx みたいなやつ。
})

続いてイベントを登録していきます。

subscriber.events.on('error', (error) => {
    console.error('Fatal database connection error:', error);
});

subscriber.notifications.on(channelName, (payload)=>{
    console.log('notification event', payload);
});

つづいてコネクトしてリッスンして終了です。

subscriber.connect();
subscriber.listenTo(channelName);

これで、無事イベントを補足することができました。

小話

最近よくコーヒーを飲んでます。ラテ系の方が濃くて美味しいですね。