GraphQL Nexus 是一個程式碼優先、型別安全的 GraphQL 結構描述建構函式庫,適用於 JavaScript/TypeScript。了解如何使用 Prisma client 和新的 nexus-prisma
外掛程式將其連接到資料庫。

⚠️ 本文已過時,因為它與 Prisma 1 相關,而 Prisma 1 現在已棄用。若要深入了解最新版本的 Prisma,請閱讀文件。 ⚠️
重點回顧:使用 GraphQL Nexus 進行程式碼優先開發
在上一篇文章中,我們介紹了 GraphQL Nexus,這是一個 GraphQL 函式庫,可為 TypeScript 和 JavaScript 啟用程式碼優先開發。透過 Nexus,GraphQL 結構描述是以程式化方式定義和實作。因此,它遵循其他語言中 GraphQL 伺服器的成熟方法,例如 sangria-graphql
(Scala)、graphlq-ruby
或 graphene
(Python)。
今天的文章是關於將基於 Nexus 的 GraphQL 伺服器連接到資料庫,使用 Prisma client 以及新的 nexus-prisma
外掛程式。稍後我們將逐步引導您從頭開始建構部落格應用程式的 GraphQL API 的實際範例。
nexus-prisma
可與 PostgreSQL、MySQL 和 MongoDB 搭配使用。在此處尋找其文件。
TLDR:nexus-prisma
外掛程式的優點
- GraphQL 中 Prisma 模型的 CRUD 運算
- 自訂您的 Prisma 模型,例如隱藏特定欄位或新增計算欄位
- 完全型別安全:GraphQL 結構描述和資料庫的一致類型集
- 與 GraphQL 生態系統相容 (例如
apollo-server
、graphql-yoga
等)
了解 nexus-prisma
工作流程
Prisma client 作為 ORM 替代方案
如果您之前未使用過 Prisma,以下是其運作方式的快速概述
- 定義您的資料模型或讓 Prisma 自行檢視您現有的資料庫
- 產生您的 Prisma client,即型別安全的資料庫用戶端
- 在應用程式 (例如 GraphQL API) 中使用 Prisma client 存取您的資料庫
nexus-prisma
外掛程式的幕後運作
將 nexus-prisma
新增至組合時,還有另一個步驟:叫用 nexus-prisma-generate
codegen CLI。它會為您的 Prisma 模型產生完整 GraphQL CRUD API 的建構區塊,例如,對於 User
模型,它包含
- 查詢
user(...):User!
:擷取單一記錄users(...):[User!]!
:擷取記錄清單usersConnection(...):UserConnection!
:Relay 連線和彙總
- 突變
createUser(...):User!
:建立新記錄updateUser(...):User
:更新記錄deleteUser(...):User
:刪除記錄updatesManyUsers(...):BatchPayload!
:大量更新多個記錄deleteManyUsers(...):BatchPayload!
:大量刪除多個記錄
- GraphQL 輸入類型
UserCreateInput
:包裝記錄的所有欄位UserUpdateInput
:包裝記錄的所有欄位UserWhereInput
:為記錄的所有欄位提供篩選器UserWhereUniqueInput
:為記錄的唯一欄位提供篩選器UserUpdateManyMutationInput
:包裝可批量更新的欄位UserOrderByInput
:指定依欄位升序或降序排序
UserCreateInput
和UserUpdateInput
在處理關係欄位的方式上有所不同。
當您使用 nexus
和 nexus-prisma
撰寫 GraphQL 伺服器程式碼時,您可以透過公開和自訂這些運算來滿足您自己的 API 需求

產生 CRUD 建構區塊後,您可以使用 nexus-prisma
中的 prismaObjectType
開始公開 (和自訂) 它們。以下程式碼片段描述了一個實作,該實作提供基於 Prisma 和 nexus-prisma
的 TODO 清單應用程式的 GraphQL API
我們將 prismaObjectType
應用於 Query
和 Mutation
。對於 Query
,我們保留所有欄位 (即 todo
、todoes
和 todoesConnection
)。對於 Mutation
,我們使用 prismaFields
自訂公開的運算。
prismaFields
可讓我們選取要公開的運算。在本例中,我們只想保留建立模型 (createTodo
) 的運算。從產生的 CRUD 建構區塊中,我們既不包含 updateTodo
也不包含 deleteTodo
,而是實作我們自己的 markAsDone(id: ID!)
突變,該突變會勾選特定的 Todo
。
範例:從標準 CRUD 到自訂 GraphQL API
現在讓我們快速瀏覽一個標準 Prisma 用例,看看如何在幾個簡單的步驟中快速建構部落格應用程式的 GraphQL API。以下是我們要執行的操作
- 使用 TypeScript 設定 Prisma 專案 (使用免費示範資料庫)
- 定義模型、遷移資料庫並產生 Prisma client
- 透過
nexus-prisma
公開完整 CRUD GraphQL API - 透過
nexus-prisma
自訂 GraphQL API
如果您想跟著操作,則需要安裝 Prisma CLI
1) 使用 TypeScript、nexus
和 nexus-prisma
設定 Prisma 專案
本節主要處理您的專案設定。如果您不想跟著編碼,可以隨時跳過它,否則請展開以下章節。
使用 Prisma CLI 建立簡單的 Prisma 專案
在互動式提示中,選取以下選項
- 選取示範伺服器 (包含 Prisma Cloud 中免費和託管的示範資料庫)
- 在瀏覽器中使用 Prisma Cloud 驗證 (如有必要)
- 返回終端機,確認所有建議的值
作為示範伺服器的替代方案,您也可以使用 Docker 在本機執行 Prisma。
接下來,您需要設定 nexus-prisma
工作流程。新增以下相依性 (在 myblog
目錄內)
接下來,將以下兩行新增到 prisma.yml
的末尾
這可確保在您變更模型時,Prisma client 以及產生的 nexus-prisma
CRUD 建構區塊都會更新。
由於我們使用 TypeScript,因此讓我們快速新增 tsconfig.json
最後,繼續新增您將用於開發的 start
指令碼。它會啟動開發伺服器,該伺服器會在背景監看您的檔案,並在您編碼時更新產生的 SDL 和 Nexus 型別。將此新增到您的 package.json
2) 定義模型、遷移資料庫和產生 Prisma client
prisma init
命令在 datamodel.prisma
中建立預設 User
模型。由於我們正在建構部落格應用程式,因此讓我們將模型調整為我們的應用程式網域
接下來,您需要透過將資料模型應用於資料庫來遷移資料庫。使用以下命令,在 datamodel.prisma
中定義的每個模型都將對應到基礎資料庫中的資料表
由於您先前在 prisma.yml
中設定了 post-deploy
勾點,因此您的 Prisma client 和 CRUD 建構區塊會自動更新。
3) 透過 nexus-prisma
公開完整 CRUD GraphQL API
在專案的早期階段,通常有助於讓 API 公開完整 CRUD 功能 - 更受限制的 API 需求通常會隨著時間推移而出現。nexus-prisma
透過提供從完整 CRUD 到自訂 API 運算的直接路徑來完美地解決這個問題。
讓我們從公開針對已定義模型的完整 CRUD 的 GraphQL API 開始 (請注意,這包括篩選器、分頁和排序)。建立一個名為 index.ts
的新檔案,並將以下程式碼新增到其中
在本簡短教學課程中,我們並未過多關注檔案結構。請查看我們的
graphql-auth
範例,以取得適當的設定和模組化結構描述。
執行 npm run start
後,您可以在 https://127.0.0.1:4000
上開啟 GraphQL 伺服器的 GraphQL Playground。透過您在上面撰寫的少量程式碼,您已經可以使用完整的 GraphQL CRUD API。
它是如何運作的?nexus-prisma-generate
產生了一個 GraphQL 結構描述,該結構描述為 Prisma 模型 (您的CRUD 建構區塊) 提供 CRUD API。此 GraphQL 結構描述遵循 OpenCRUD 規格。使用 prismaObjectType
函數,您現在可以公開和自訂該結構描述的運算。
prismaObjectType
和 prismaFields
使用白名單方法,這表示您需要明確列出要公開的欄位。萬用字元運算子 *
包含所有欄位。

4) 透過 nexus-prisma
自訂 GraphQL API
在本節中,我們將了解如何自訂 nexus-prisma
中的 CRUD GraphQL API。具體來說,我們將要
- 從
User
模型中隱藏欄位 - 將計算欄位新增到
Post
模型 - 隱藏
createPost
和updatePost
突變 - 新增兩個自訂
createDraft
和publish
突變
4.1) 從 User
模型中隱藏欄位
在本節中,我們將從 User
模型中隱藏 email
欄位。
若要自訂模型,我們需要將 prismaObjectType
函數應用於模型,並將 definition(t)
函數作為選項傳遞
透過在模型 t
上呼叫 prismaFields
,我們可以自訂公開的欄位 (及其引數)。由於 email
未包含在清單中,因此它會從我們的 GraphQL API 中移除。

若要套用變更,您需要明確地將 User
傳遞到 makePrismaSchema
內的 types
陣列
請注意,您的編輯器能夠根據產生的 CRUD 建構區塊建議要傳遞到 prismaObjectType
和 prismaFields
中的內容。這表示當您輸入 prismaObjectType('')
並按下 ctrl+space 時,它會建議所有產生的 CRUD 建構區塊的名稱。當呼叫 t.prismaFields([''])
時,它會建議 t
的欄位
4.2) 將計算欄位新增到 Post
模型
使用 nexus-prisma
的新程式碼優先方法也讓將計算欄位新增到 Prisma 模型變得容易。假設您想要將欄位新增到 Post
,該欄位始終傳回完全大寫的 title
。以下是如何實作它
我們使用來自 graphql-nexus
的 t.string(...)
API 將新欄位新增到我們的模型。由於它是計算欄位 (因此無法由 nexus-prisma
自動解析),因此我們也需要將解析器附加到它。

與之前一樣,您需要明確地將自訂的 Post
模型新增到 types
陣列
4.3) 隱藏 createPost
和 updatePost
突變
以我們從 User
模型中隱藏 email
欄位的相同方式,我們也可以從屬於產生的 nexus-prisma
CRUD 建構區塊的 Query
/Mutation
類型中隱藏運算。
若要隱藏 createPost
和 updatePost
,我們再次需要將 definition(t)
作為選項傳遞給 prismaObjectType
。請注意,一旦我們在類型上呼叫 prismaFields
,我們就需要明確列出我們要保留的所有欄位 (空陣列將被解讀為「不保留任何運算」)
產生的 CRUD GraphQL API 也包含批次和 upsert 運算,為簡潔起見,我們在此處將其排除。
4. 新增兩個自訂 createDraft
和 publish
突變
最後,我們將兩個自訂突變新增到我們的 GraphQL API。以下是它們的 SDL 定義的樣子
若要實作這些突變,您需要將兩個欄位 (透過從 nexus
API 呼叫 t.field( ... )
) 新增到 Mutation
類型
請務必從 nexus
套件匯入 stringArg
和 idArg
,以使此操作生效。
GraphQL Nexus 也會產生 GraphQL 結構描述的 SDL 版本,您可以在 ./generated/schema.graphql
中找到它。我們的 GraphQL API 的最終版本如下所示
從我們的程式碼優先 GraphQL 文章中獲得 3 個主要重點
這是我們關於程式碼優先 GraphQL 伺服器開發系列文章的最後一部分。
GraphQL Nexus 和 nexus-prisma
外掛程式實作了我們從作為 GraphQL 生態系統的活躍貢獻者超過兩年所收集的經驗。在發現 SDL 優先方法存在太多問題後,我們對目前正在興起的新程式碼優先工具感到非常興奮。
我們堅信 GraphQL Nexus (和其他程式碼優先方法,例如 TypeGraphQL) 將徹底改變未來建構 GraphQL 結構描述的方式。
以下是我們從本系列中獲得的主要重點
- 程式碼優先方法可讓您以符合語言習慣的方式建構 GraphQL 伺服器,而無需額外的工具 («您唯一需要的工具是您的程式設計語言»),同時保留 SDL 作為通訊工具的優點。
- GraphQL Nexus 讓開發人員可以使用彈性且型別安全的 API 建構其結構描述。由於自動完成和建置時錯誤檢查,開發人員獲得絕佳的體驗。
nexus-prisma
外掛程式建構於 Prisma 模型之上,讓開發人員可以透過公開和自訂自動產生的 CRUD 建構區塊來建構 GraphQL API。
立即試用 nexus-prisma
🙌
您有多種方法可以試用 nexus-prisma
。您可以依照文件中的開始使用章節,或瀏覽我們的TypeScript GraphQL 範例。
請透過開啟 GitHub 問題或在我們的 Slack 中聯絡我們,分享您的意見反應。
非常感謝我們的開放原始碼工程師 Flavian Desverne 在 nexus-prisma
外掛程式上所做的出色工作 💪✨
不要錯過下一篇文章!
訂閱 Prisma 電子報