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

共有Prisma Client拡張機能

ユーザーは、自身のPrisma Client拡張機能をパッケージまたはモジュールとして他のユーザーと共有したり、他のユーザーが作成した拡張機能をプロジェクトにインポートしたりできます。

共有可能な拡張機能を作成したい場合は、prisma-client-extension-starterテンプレートを使用することをお勧めします。

Prismaの公式Client拡張機能とコミュニティによって作成された拡張機能の例を見るには、このページをご覧ください。

共有パッケージ拡張機能をインストールする

プロジェクトでは、他のユーザーが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ではなく、$extendsステートメントの定数名を使用してください。上記の例では、xprisma.user.findOrCreateは機能しますが、元のprismaは変更されないため、prisma.user.findOrCreateは機能しません。

共有可能な拡張機能を作成する

他のユーザーが使用でき、かつ自身のスキーマに特化していない拡張機能を作成したい場合、Prisma ORMは共有可能な拡張機能を作成するためのユーティリティを提供します。

共有可能な拡張機能を作成するには

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

拡張機能を定義する

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

Prisma.defineExtensionの利点は、拡張機能の作成者と共有拡張機能のユーザーに対して、開発中に厳密な型チェックと自動補完を提供することです。

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

$allModels下のメソッドを含む拡張機能は、特定のモデルではなくすべてのモデルに適用されます。同様に、$allOperations下のメソッドは、resultqueryといった名前付きコンポーネントではなく、クライアントインスタンス全体に適用されます。

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

例えば、ジェネリック拡張機能は次の形式をとることができます。

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で詳しく学ぶ: クライアントレベルのメソッドの使用を必要とするクライアント拡張機能がトランザクションを黙って無視する

以下の状況では、拡張機能がラップする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]
},
},
},
})
})

高度な型安全性: ジェネリック拡張機能を定義するための型ユーティリティ

型ユーティリティを使用して、共有拡張機能の型安全性を向上させることができます。

© . All rights reserved.