Prisma Client 擴充套件(預覽版)開啟了許多新的使用場景。本文將探討如何使用擴充套件為 Prisma Client 新增自定義功能。
目錄
簡介
Prisma Client 擴充套件提供了一種功能強大的新方式,以型別安全的方式為 Prisma 新增功能。藉助它們,您將能夠為 ORM 尚未原生支援的問題建立簡單、靈活的解決方案。您可以在 TypeScript 或 JavaScript 中定義擴充套件,組合它們,甚至建立多個帶有不同擴充套件的輕量級 Prisma Client 例項。
準備就緒後,您可以將您的擴充套件以程式碼片段的形式分享給社群,或者透過打包併發布到 npm 來分享。本文將向您展示擴充套件的可能性,並希望啟發您建立和分享自己的擴充套件!
注意:我們相信 Prisma Client 擴充套件將在使用 Prisma 時開闢許多新的可能性。然而,僅僅因為一個問題可以用擴充套件解決,並不意味著它將來不會透過一流的功能來解決。我們的目標之一是與社群一起實驗和探索解決方案,然後再將它們原生整合到 Prisma 中。
使用 Prisma Client 擴充套件
要使用 Prisma Client 擴充套件,您需要首先在 Prisma schema 檔案中啟用 clientExtensions 預覽功能
然後,您可以在 Prisma Client 例項上呼叫 $extends 方法。這將返回一個新的“擴充套件”客戶端例項,而不會修改原始例項。您可以鏈式呼叫 $extends 來使用多個擴充套件,並建立帶有不同擴充套件的獨立例項
擴充套件的元件
擴充套件中可以包含四種不同型別的元件
- 模型(Model)元件允許您為模型新增新方法。這是在預設方法(如
findMany、create等)之外新增新操作的便捷方式。您可以將其用作常用查詢方法的儲存庫,封裝模型的業務邏輯,或執行您可能使用類上的靜態方法進行的任何操作。 - 客戶端(Client)元件可用於向 Prisma Client 本身新增新的頂級方法。使用此功能擴充套件客戶端,使其具有不與特定模型繫結的功能。
- 查詢(Query)元件允許您掛接到查詢生命週期,並以型別安全的方式執行副作用、修改查詢引數或更改結果。這些是 中介軟體 的替代方案,它們提供完整的型別安全,並且可以臨時應用於不同的擴充套件客戶端例項。
- 結果(Result)元件將自定義欄位和方法新增到查詢結果物件。這些允許您實現虛擬/計算欄位,在一個地方定義模型例項的業務邏輯,並轉換查詢返回的資料。
單個擴充套件可以包含一個或多個元件,以及一個可選的名稱,用於在錯誤訊息中顯示
要檢視定義每種擴充套件元件的完整語法,請參閱文件。
共享擴充套件
您可以使用 Prisma.defineExtension 工具定義一個可以與其他使用者共享的擴充套件
將共享擴充套件釋出到 npm 時,我們建議使用 prisma-extension-<package-name> 命名約定。這將使使用者更容易在其應用程式中找到並安裝您的擴充套件。
例如,如果您釋出一個包名為 prisma-extension-find-or-create 的擴充套件,使用者可以這樣安裝它
然後在他們的應用程式中使用該擴充套件
閱讀我們關於共享擴充套件的文件獲取更多詳細資訊。
示例使用場景
我們整理了一系列可以用擴充套件解決的使用場景,並建立了一些如何編寫這些擴充套件的示例。讓我們看看這些使用場景及其實現
注意:Prisma Client 擴充套件仍處於預覽階段,並且下面的一些示例可能存在某些限制。已知限制會在示例的
README檔案中列出,位於 GitHub 上。
示例:計算欄位
在 GitHub 上檢視完整示例
此示例演示如何建立 Prisma Client 擴充套件,為 Prisma 模型新增虛擬/計算欄位。這些欄位不包含在資料庫中,而是在執行時計算。
計算欄位是型別安全的,可以返回從簡單值到複雜物件,甚至是可作為模型例項方法的函式。計算欄位必須指定它們依賴於哪些其他欄位,並且可以由其他計算欄位組合/重用。
示例:轉換欄位
在 GitHub 上檢視完整示例
此示例演示如何使用 Prisma Client 擴充套件來轉換 Prisma 查詢返回結果中的欄位。在此示例中,date 欄位被轉換為特定區域設定的相對字串。
這展示了一種在應用程式資料訪問層實現國際化 (i18n) 的方法。然而,這種技術可以使您對查詢結果中的欄位實現任何型別的自定義轉換或序列化/反序列化。
示例:模糊化欄位
在 GitHub 上檢視完整示例
此示例是前面轉換欄位示例的特殊情況。它使用擴充套件來隱藏 User 模型上的敏感 password 欄位。password 列不包含在底層 SQL 查詢的選擇列中,並且在使用者結果物件上訪問時將解析為 undefined。它也可以解析為任何其他值,例如模糊化字串,如 "********"。
示例:例項方法
在 GitHub 上檢視完整示例
此示例演示如何向 Prisma 結果物件新增類似Active Record的介面。它使用 result 擴充套件,將 save 和 delete 方法直接新增到 Prisma Client 方法返回的 User 模型物件。
此技術可用於透過行為自定義 Prisma 結果物件,類似於向模型類新增例項方法。
示例:靜態方法
在 GitHub 上檢視完整示例
此示例演示如何建立 Prisma Client 擴充套件,為 User 模型新增 signUp() 和 findManyByDomain() 方法。
此技術可用於抽象通用查詢/操作的邏輯,建立類似倉庫的介面,或執行您可能使用靜態類方法進行的任何操作。
示例:模型過濾器
在 GitHub 上檢視完整示例
此示例演示了一個 Prisma Client 擴充套件,它為模型添加了可重用過濾器,這些過濾器可以組合並傳遞給查詢的 where 條件。複雜、常用的過濾條件可以編寫一次,並透過擴充套件的 Prisma Client 例項在多個查詢中訪問。
示例:只讀客戶端
在 GitHub 上檢視完整示例
此示例建立了一個只允許讀取操作(如 findMany 和 count),而不允許寫入操作(如 create 或 update)的客戶端。呼叫寫入操作將在執行時和 TypeScript 編譯時導致錯誤。
示例:輸入轉換
在 GitHub 上檢視完整示例
此示例建立了一個擴充套件客戶端例項,它修改查詢引數以僅包含 published 帖子。
由於 query 擴充套件允許修改查詢引數,因此可以使用此方法應用各種預設過濾器。
示例:輸入驗證
在 GitHub 上檢視完整示例
此示例使用 Prisma Client 擴充套件在建立和更新資料庫物件時執行自定義執行時驗證。它使用 Zod 執行時模式來檢查傳遞給 Prisma 寫入方法的資料是否有效。
這可用於清理使用者輸入或拒絕不符合您的業務邏輯規則定義的某些條件的突變。
示例:JSON 欄位型別
在 GitHub 上檢視完整示例
下一個示例結合了輸入驗證和轉換欄位示例中展示的方法,為 Json 欄位提供靜態和執行時型別。它使用 Zod 解析欄位資料並推斷靜態 TypeScript 型別。
此示例包含一個帶有 JSON 配置檔案欄位的 User 模型,該欄位具有稀疏結構,可能因使用者而異。該擴充套件分為兩部分
- 一個
result擴充套件,新增一個計算的profile欄位。該欄位使用ProfileZod 模式來解析底層無型別的profile欄位。TypeScript 從解析器推斷靜態資料型別,因此查詢結果同時具有靜態和執行時型別安全。 - 一個
query擴充套件,用於解析User模型的寫入方法(如create和update)的輸入資料中的profile欄位。
示例:查詢日誌
在 GitHub 上檢視完整示例
此示例演示如何使用 Prisma Client 擴充套件來執行與中介軟體相似的任務。在此示例中,一個 query 擴充套件會跟蹤完成每個查詢所需的時間,並記錄結果以及查詢和引數本身。
此技術可用於執行通用日誌記錄、發出事件、跟蹤使用情況等。
注意:您可能對OpenTelemetry 追蹤和指標功能(均處於預覽階段)感興趣,它們提供了有關效能以及 Prisma 如何與資料庫互動的詳細見解。
示例:重試事務
在 GitHub 上檢視完整示例
此示例演示如何使用 Prisma Client 擴充套件來自動重試因寫入衝突/死鎖超時而失敗的事務。失敗的事務將使用指數退避和抖動重試,以減少高流量下的爭用。
示例:無回撥互動式事務
在 GitHub 上檢視完整示例
此示例展示了一個 Prisma Client 擴充套件,它添加了一個新的 API,用於啟動互動式事務而無需回撥。
這賦予您互動式事務(例如讀-修改-寫週期)的全部功能,但採用更命令式的 API。在某些情況下,這可能比互動式事務的常規回撥式 API 更方便。
示例:審計日誌上下文
在 GitHub 上檢視完整示例
此示例演示如何使用 Prisma Client 擴充套件將當前應用程式使用者的 ID 作為上下文提供給 Postgres 中的審計日誌觸發器。使用者 ID 包含在跟蹤表中每一行更改的審計跟蹤中。
此解決方案的詳細說明可在GitHub 上示例的 README 中找到。
示例:行級安全
在 GitHub 上檢視完整示例
此示例演示如何使用 Prisma Client 擴充套件,透過 Postgres 中的行級安全 (RLS) 在多租戶應用程式中隔離租戶之間的資料。
此解決方案的詳細說明可在GitHub 上示例的 README 中找到。
告訴我們您的想法
我們希望您和我們一樣對 Prisma Client 擴充套件所創造的可能性感到興奮!
💡 您可以在這個 GitHub issue 中與我們分享您的反饋。
不要錯過下一篇文章!
訂閱 Prisma 新聞通訊