pg パッケージ) は、Node.js 向けの Postgres ドライバーとして最も広く利用されています。このガイドでは、TLS 証明書の検証を完全に有効にした pg.Pool 経由で ClickHouse Managed Postgres に接続し、2 つのテーブルを作成します。続いて、トランザクション内で口座間の送金を行い、小さな node:http サーバーからデータを返します。
前提条件
- Node.js 20.6 以降 (組み込みの
--env-fileフラグを使用するため) 。本ガイドは Node.js 24.21.0 およびpg8.23.1 で動作確認済みです。 - ClickHouse Cloud アカウント
- データベース作成用の
psql
ClickHouse Managed Postgres サービスを作成する
ClickHouse Cloud コンソールで New service をクリックし、Postgres を選択します。インスタンスは数分で利用可能になります。詳しい手順については、クイックスタートを参照してください。接続情報を取得する
サービスの左サイドバーで Connect をクリックします。Directly を選択した状態で、url タブから接続 URL をコピーします。Use SSL はオフのままにしてください。このアプリでは、CA 証明書を URL に含めるのではなくコード内で指定します (接続プールを設定するを参照) 。 このガイドでは、ポート5432 で Postgres に直接接続します。長時間稼働する Node.js サーバーは pg.Pool によって独自の接続プールをすでに管理しているため、Postgres の前段に別途プーラーを置く必要はありません。多数のプロセスやサーバーレス関数を実行する場合は、代わりに同梱の PgBouncer を使用してください。詳しくは PgBouncer を使用するを参照してください。
次に、インスタンスの CA 証明書をダウンロードします。Use SSL をオンにして Download CA certificate をクリックするか、Settings → CA Certificate → Download CA certificate に移動します。この証明書はインスタンスごとに異なります。
プロジェクトのセットアップ
プロジェクトを作成し、pg をインストールします。
.mjs の ES モジュールで記述しています。そのため、package.json で CommonJS と ES モジュールのどちらを使用していても動作します。
データベースを作成する
ダウンロードした<service-name>-ca-certificate.pem ファイルをプロジェクトディレクトリに移動し、ファイル名を ca-certificate.pem にリネームします。続いて、アプリケーション用のデータベースを作成します。
guide_nodejs に変更したもの) と証明書のパスを記述した .env ファイルを作成します。
.env
@、/、# などの文字が含まれている場合は、URL 内でそれらの文字をパーセントエンコードしてください。
接続プールを設定する
db.mjs を作成します。このファイルは、アプリの他の部分から共有される単一の pool をエクスポートします。
db.mjs
ssl: { ca } を渡すと、sslmode=verify-full と同等の動作になります。つまり pg は、サーバー証明書がインスタンスの CA によって署名されていること、および証明書がホスト名と一致することを検証します。rejectUnauthorized のデフォルトは true です。false には設定しないでください。
スキーマを作成する
setup.mjs を作成します。このスクリプトはテーブルを作成し、パラメータ化クエリで 2 つのアカウントを挿入してから、それらを読み出して確認します。
setup.mjs
$1、$2、…) として渡してください。pg はパラメータをクエリテキストとは別に送信するため、SQL インジェクションを防げます。ANY($1) クエリの例のように、JavaScript の配列は Postgres の配列にマッピングされます。
実行します:
pg は精度が失われないよう、numeric (および bigint) の値を文字列として返します。数値として扱う必要がある場合は、明示的に変換してください。
トランザクション内でクエリを実行する
トランザクションは単一の接続上で実行する必要があります。そのため、pool.connect でクライアントを取得し、使用後は必ず解放してください。transfer.mjs を作成します。
transfer.mjs
pool.query を使用しないでください。pool.query は呼び出しごとに異なる接続で実行される可能性があります。
HTTP 経由でデータを提供する
server.mjs を作成します。このサーバーは、アカウントと振替のデータをポート 3107 で JSON として返し、新しい振替を受け付けます。また、SIGINT (Ctrl+C) または SIGTERM を受け取ると正常にシャットダウンします。
server.mjs
pool.end は、リクエストのたびに呼び出すのではなく、プロセスの終了時に一度だけ呼び出してください。このメソッドは、チェックアウト中のクライアントがすべて解放されるのを待ってから、すべての接続を閉じます。
動作確認
サーバーを起動します。alice の口座から引き落とされていましたが、ROLLBACK によって取り消されました。ブラウザで http://localhost:3107/accounts を開き、残高を確認してください。レスポンスは次のようになります。
pg_stat_ssl に対してクエリを実行します。
DATABASE_CA_CERT に別の証明書を指定すると、接続は unable to verify the first certificate というエラーで失敗します。これにより、サーバー証明書が実際に検証されていることを確認できます。
最後に、Ctrl+C でサーバーを停止します。SIGINT received, shutting down に続いて Pool closed が出力されます。
コンソールでデータを確認することもできます。SQL コンソール を開き、guide_nodejs データベースを展開して、accounts テーブルを開きます。
PgBouncer を使用する
同梱の PgBouncer 経由で接続するには、Connect モーダルで via PgBouncer を選択し、DATABASE_URL のポートに 6432 を指定します。コードを変更する必要はなく、CA 証明書も同じものをそのまま使用できます。
PgBouncer はトランザクションプーリングモードで動作するため、トランザクションごとに異なる Postgres 接続で実行される場合があります。pg を使用する場合の挙動は次のとおりです。
- パラメータ化クエリ、名前付きプリペアドステートメント (
pool.query({ name, text, values })) 、およびpool.connectを使用したトランザクションは、本ガイドで示したとおりに動作します。 - SQL レベルの
PREPAREとEXECUTE、およびSETで変更した session 設定は、トランザクションをまたいで保持されません。代わりに、トランザクション内でSET LOCALを使用してください。 pg_stat_sslが報告するのは PgBouncer と Postgres 間の接続であるため、前述の TLS 確認クエリはssl: falseを返します。ただし、アプリケーションから PgBouncer への接続は引き続き検証されており、誤った CA 証明書を使用すれば同様に接続に失敗します。