共有 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 は共有可能なエクステンションを作成するためのユーティリティを提供します。
共有可能なエクステンションを作成するには
Prisma.defineExtension
を使用してエクステンションをモジュールとして定義する$allModels
や$allOperations
など、$all
プレフィックスで始まるメソッドのいずれかを使用する
エクステンションを定義する
Prisma.defineExtension
メソッドを使用して、エクステンションを共有可能にします。これを使用して、エクステンションをパッケージ化して、エクステンションを別のファイルに分離したり、npm パッケージとして他のユーザーと共有したりできます。
Prisma.defineExtension
の利点は、開発中のエクステンションの作成者と共有エクステンションのユーザーに、厳密な型チェックと自動補完を提供することです。
ジェネリックメソッドを使用する
$allModels
の下にあるメソッドを含むエクステンションは、特定のもののではなく、すべてのモデルに適用されます。同様に、$allOperations
の下にあるメソッドは、クライアントインスタンス全体に適用され、result
や query
などの名前付きコンポーネントには適用されません。
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]
},
},
},
})
})
高度な型安全性: ジェネリックエクステンションを定義するための型ユーティリティ
型ユーティリティ を使用して、共有エクステンションの型安全性を向上させることができます。