メインコンテンツにスキップ

共有 Prisma Client エクステンション

他のユーザーと Prisma Client エクステンション をパッケージまたはモジュールとして共有し、他のユーザーが作成したエクステンションをプロジェクトにインポートできます。

共有可能なエクステンションを構築する場合は、prisma-client-extension-starter テンプレートを使用することもお勧めします。

Prisma の公式クライアントエクステンションとコミュニティによって作成されたエクステンションの例を調べるには、こちらのページをご覧ください。

共有パッケージ化されたエクステンションをインストールする

プロジェクトでは、他のユーザーが npm に公開した Prisma Client エクステンションをインストールできます。これを行うには、次のコマンドを実行します

npm install prisma-extension-<package-name>

たとえば、利用可能なエクステンションのパッケージ名が prisma-extension-find-or-create の場合、次のようにインストールできます。

npm install prisma-extension-find-or-create

上記の例から find-or-create エクステンションをインポートし、クライアントインスタンスをラップするには、次のコードを使用できます。この例では、エクステンション名が findOrCreate であると仮定しています。

import findOrCreate from 'prisma-extension-find-or-create'

const prisma = new PrismaClient().$extends(findOrCreate)
const user = await prisma.user.findOrCreate()

エクステンションでメソッドを呼び出すときは、元の prisma は変更されていないため、prisma ではなく、$extends ステートメントからの定数名を使用してください。上記の例では、xprisma.user.findOrCreate は機能しますが、prisma.user.findOrCreate は機能しません。

共有可能なエクステンションを作成する

他のユーザーが使用でき、スキーマ専用ではないエクステンションを作成する場合、Prisma ORM は共有可能なエクステンションを作成するためのユーティリティを提供します。

共有可能なエクステンションを作成するには

  1. Prisma.defineExtension を使用してエクステンションをモジュールとして定義する
  2. $allModels$allOperations など、$all プレフィックスで始まるメソッドのいずれかを使用する

エクステンションを定義する

Prisma.defineExtension メソッドを使用して、エクステンションを共有可能にします。これを使用して、エクステンションをパッケージ化して、エクステンションを別のファイルに分離したり、npm パッケージとして他のユーザーと共有したりできます。

Prisma.defineExtension の利点は、開発中のエクステンションの作成者と共有エクステンションのユーザーに、厳密な型チェックと自動補完を提供することです。

ジェネリックメソッドを使用する

$allModels の下にあるメソッドを含むエクステンションは、特定のもののではなく、すべてのモデルに適用されます。同様に、$allOperations の下にあるメソッドは、クライアントインスタンス全体に適用され、resultquery などの名前付きコンポーネントには適用されません。

client コンポーネントは常にクライアントインスタンスに適用されるため、client コンポーネントで $all プレフィックスを使用する必要はありません。

たとえば、ジェネリックエクステンションは次の形式を取る場合があります

export default Prisma.defineExtension({
name: 'prisma-extension-find-or-create', //Extension name
model: {
$allModels: {
// new method
findOrCreate(/* args */) {
/* code for the new method */
return query(args)
},
},
},
})

Prisma Client 操作を変更するさまざまな方法については、次のページを参照してください。

4.16.0 より前のバージョン

Prisma インポートは、以下のスニペットに示す別のパスから利用できます

import { Prisma } from '@prisma/client/scripts/default-index'

export default Prisma.defineExtension({
name: 'prisma-extension-<extension-name>',
})

共有可能なエクステンションを npm に公開する

その後、npm でエクステンションを共有できます。パッケージ名を選択するときは、見つけてインストールしやすくするために、prisma-extension-<package-name> という規則を使用することをお勧めします。

パッケージ化されたエクステンションからクライアントレベルのメソッドを呼び出す

警告

現在、PrismaClient を参照し、以下の例のようにクライアントレベルのメソッドを呼び出すエクステンションには制限があります。

トランザクション(インタラクティブまたはバッチ処理)の内部からエクステンションをトリガーすると、エクステンションコードは新しい接続でクエリを発行し、現在のトランザクションコンテキストを無視します。

詳細については、GitHub のこの issue を参照してください: クライアントレベルのメソッドの使用を必要とするクライアントエクステンションは、トランザクションをサイレントに無視します

次の状況では、エクステンションがラップする Prisma Client インスタンスを参照する必要があります

  • パッケージ化されたエクステンションで、$queryRaw などの クライアントレベルのメソッド を使用する場合。
  • パッケージ化されたエクステンションで、複数の $extends 呼び出しをチェーンしたい場合。

ただし、誰かがパッケージ化されたエクステンションをプロジェクトに含める場合、コードは Prisma Client インスタンスの詳細を知ることができません。

このクライアントインスタンスは次のように参照できます

Prisma.defineExtension((client) => {
// The Prisma Client instance that the extension user applies the extension to
return client.$extends({
name: 'prisma-extension-<extension-name>',
})
})

例:

export default Prisma.defineExtension((client) => {
return client.$extends({
name: 'prisma-extension-find-or-create',
query: {
$allModels: {
async findOrCreate({ args, query, operation }) {
return (await client.$transaction([query(args)]))[0]
},
},
},
})
})

高度な型安全性: ジェネリックエクステンションを定義するための型ユーティリティ

型ユーティリティ を使用して、共有エクステンションの型安全性を向上させることができます。