在本系列中,您將學習如何使用 React、GraphQL、Prisma 和其他一些有助於將這三者結合在一起的工具,來實作端對端類型安全。
目錄
- 簡介
- 啟動 GraphQL 伺服器
- 設定 Schema Builder
- 定義
Date
純量類型 - 新增 Pothos Prisma 外掛程式
- 建立 Prisma Client 的可重複使用執行個體
- 定義您的 GraphQL 類型
- 實作您的查詢
- 套用 GraphQL Schema
- 摘要 & 接下來的步驟
簡介
在本節中,您將以前一篇文章在本系列中設定的專案為基礎,擴充 GraphQL API 的功能。
在建構此 API 時,您將專注於確保您與資料庫的互動、解析器內部的資料處理以及資料回應都是類型安全的,並且這些類型是同步的。
如果您錯過了本系列文章的第一部分,以下是您將在本應用程式中使用的技術以及一些先決條件的快速概述。
您將使用的技術
以下是您將在本系列中使用的主要工具
- Prisma 作為物件關聯對應 (ORM)
- PostgreSQL 作為資料庫
- Railway 來託管您的資料庫
- TypeScript 作為程式設計語言
- GraphQL Yoga 作為 GraphQL 伺服器
- Pothos 作為程式碼優先的 GraphQL Schema Builder
- Vite 來管理和建構您的前端專案
- React 作為前端 JavaScript 程式庫
- GraphQL Codegen 根據 GraphQL Schema 為前端產生類型
- TailwindCSS 用於應用程式的樣式設計
- Render 來部署您的 API 和 React 應用程式
預期知識
雖然本系列將嘗試從初學者的角度詳細介紹所有內容,但以下知識將會有所幫助
- JavaScript 或 TypeScript 的基本知識
- GraphQL 的基本知識
- React 的基本知識
開發環境
若要跟著提供的範例操作,您需要具備
- Node.js 已安裝。
- Prisma VSCode 擴充功能 已安裝。(選用)
啟動 GraphQL 伺服器
建構 GraphQL API 時,您需要做的第一件事是執行中的 GraphQL 伺服器。在本應用程式中,您將使用 GraphQL Yoga 作為您的 GraphQL 伺服器。
安裝 @graphql-yoga/node
和 graphql
套件以開始使用
安裝這些套件後,您現在可以啟動自己的 GraphQL 伺服器。前往 src/index.ts
。將現有內容替換為以下程式碼片段
以上程式碼執行以下操作
- 從 GraphQL Yoga 匯入
createServer
函數 - 建立變數以保存 API 的連接埠,如果環境中沒有連接埠,則預設為
4000
- 建立 GraphQL 伺服器的執行個體
- 在連接埠
4000
上啟動伺服器,並讓主控台知道伺服器已啟動並執行中
如果您啟動伺服器,您將可以存取執行中的(空的) GraphQL API
注意:GraphQL 伺服器已啟動並執行中,但由於您尚未定義任何查詢或變動,因此無法使用。
設定 Schema Builder
GraphQL 使用強型別 Schema 來定義使用者如何與 API 互動以及應傳回哪些資料。有兩種不同的方法來建構 GraphQL Schema:程式碼優先和 SDL 優先。
- 程式碼優先:您的應用程式程式碼定義並產生 GraphQL Schema
- SDL 優先:您手動編寫 GraphQL Schema
在本應用程式中,您將採用程式碼優先方法,使用名為 Pothos 的熱門 Schema Builder。
若要開始使用 Pothos,您首先需要安裝核心套件
接下來,建立 Pothos Schema Builder 的執行個體作為可共用模組。在 src
資料夾中,建立名為 builder.ts
的新檔案,其中將保存此模組
現在,從 @pothos/core
套件匯入預設匯出,並匯出名為 builder
的執行個體
定義 Date
純量類型
依預設,GraphQL 僅支援一組有限的純量資料類型
- Int
- Float
- String
- Boolean
- ID
但是,如果您回想一下您的 Prisma Schema,您會記得定義了一些使用 DateTime
資料類型的欄位。若要在您的 GraphQL API 中處理這些欄位,您需要定義自訂 Date
純量類型。
幸運的是,由於開放原始碼社群,預先建立的自訂純量類型定義可用。您將使用的類型定義稱為 graphql-scalars
您需要向 Schema Builder 註冊 Date
純量,以讓其知道如何處理日期。Schema Builder 接受 泛型,您可以在其中指定各種組態。
進行以下變更以註冊 Data
純量類型
以下是以上程式碼片段中的變更。您
- 匯入了
Date
純量類型的解析器,該解析器處理在您的 API 中將值轉換為正確的日期類型 - 使用
SchemaBuilder
的Scalars
組態註冊名為"Date"
的新純量類型,並組態 JavaScript 類型,以便在存取和驗證此類型的欄位時使用 - 透過提供匯入的
DateResolver
,讓 Builder 知道如何處理已定義的Date
純量類型
在您的 GraphQL 物件類型和解析器中,現在可以使用 Date
純量類型。
新增 Pothos Prisma 外掛程式
您需要做的下一件事是定義您的 GraphQL 物件類型。這些類型定義您的 API 將透過查詢公開的物件和欄位。
Pothos 有一個很棒的 外掛程式,適用於 Prisma,可讓此程序更順暢,並在您的 GraphQL 類型和資料庫 Schema 之間提供類型安全。
注意:Pothos 可以在不使用外掛程式的情況下以類型安全的方式與 Prisma 一起使用,但該程序非常手動。請參閱此處的詳細資訊。
首先,安裝外掛程式
此外掛程式提供 Prisma 產生器,可產生 Pothos 所需的類型。將產生器新增至您的 Prisma Schema,位於 prisma/schema.prisma
中
新增後,您將需要一種方法來產生 Pothos 的 Artifact。每次稍後在本系列中部署此應用程式時,您都需要安裝此 API 的 Node 模組並重新產生 Prisma Client,因此請繼續在 package.json
中建立新的 script
以處理此問題
現在您可以執行該命令來安裝您的 Node 模組,並重新產生 Prisma Client 和 Pothos 輸出
當您執行上述命令時,您應該會看到 Prisma Client 和 Pothos 整合都已產生。
現在這些類型已產生,請前往 src/builder.ts
。在這裡,您將匯入 PrismaPlugin
和產生的 Pothos 類型,並將其套用至您的 Builder
一旦您新增產生的類型,您會注意到在 SchemaBuilder
的執行個體化中發生 TypeScript 錯誤。
Pothos 非常聰明,它知道由於您正在使用 Prisma 外掛程式,因此您需要向 Builder 提供 prisma
執行個體。Pothos 使用此執行個體來推斷有關 Prisma Client 中類型的資訊。在下一步中,您將建立該執行個體並將其新增至 Builder。
現在,在 Builder 執行個體中註冊 Prisma 外掛程式和產生的類型,以讓 Pothos 知道它們
您將再次在此時看到 TypeScript 錯誤。這是因為 builder
現在預期將 Prisma Client 的執行個體提供給函數。
在下一步中,您將執行個體化 Prisma Client 並在此處的 builder
中提供它。
建立 Prisma Client 的可重複使用執行個體
您現在需要建立 Prisma Client 的可重複使用執行個體,該執行個體將用於查詢您的資料庫,並提供上一步中 Builder 所需的類型。
在 src
資料夾中建立名為 db.ts
的新檔案
在該檔案中,匯入 Prisma Client 並建立名為 prisma
的 Client 執行個體。匯出該已執行個體化的 Client
將 prisma
變數匯入 src/builder.ts
並將其提供給 builder
以消除 TypeScript 錯誤
Pothos Prisma 外掛程式現在已完全組態並可供使用。這會採用 Prisma 產生的類型,並讓您可以輕鬆存取 GraphQL 物件類型和查詢中的這些類型。
關於此程式的酷炫之處在於,您現在擁有單一的事實來源 (Prisma Schema),可處理資料庫中的類型、用於查詢資料庫的 API 以及 GraphQL Schema。
接下來,您將看到實際運作情況!
定義您的 GraphQL 類型
此時,您將使用您使用 Prisma 外掛程式組態的 Builder 來定義 GraphQL 物件類型。
注意:當您已經在 Prisma Schema 中定義了資料的形狀時,手動定義 GraphQL 物件類型似乎是多餘的。Prisma Schema 定義資料庫中資料的形狀,而 GraphQL Schema 定義 API 中可用的資料。
在 src
中建立名為 models
的新資料夾。然後在該新資料夾中建立 User.ts
檔案
您將在此處定義 User
物件類型及其相關查詢,您將透過 GraphQL API 公開這些查詢。匯入 builder
執行個體
由於您正在使用 Pothos 的 Prisma 外掛程式,因此 builder
執行個體現在有一個名為 prismaObject
的方法,您將使用該方法來定義您的物件類型。
該方法接受兩個參數
name
:此新類型代表的 Prisma 模型名稱options
:正在定義之類型的組態
使用該方法建立 "User"
類型
注意:如果您在
name
欄位中輸入之前在空引號集中按下 Ctrl + Space,您應該會獲得一些不錯的自動完成功能,其中包含 Prisma Schema 中可用模型的清單,這要歸功於 Prisma 外掛程式。
在 options
物件中,新增 fields
索引鍵,該索引鍵使用 Pothos 的 "expose" 函數定義 id
、name
和 messages
欄位
注意:當您開始輸入欄位名稱時,按下 Ctrl + Space 將為您提供目標模型中符合您正在使用的 "expose" 函數資料類型的欄位清單。
以上函數定義 GraphQL 類型定義並在 builder
執行個體中註冊它。從 builder
產生 Schema 實際上並不會在您可以查看的檔案系統中儲存 GraphQL Schema,但是 User
的結果類型定義將如下所示
接下來,在同一個資料夾中新增另一個名為 Message.ts
的檔案
此檔案將與 User.ts
檔案類似,但它將定義 Message
模型。
定義 id
、body
和 createdAt
欄位。請注意,createdAt
欄位在您的 Prisma Schema 中具有 DateTime
類型,並且需要自訂組態來定義您定義的自訂 date
純量類型
此函數將產生以下 GraphQL 物件類型
實作您的查詢
目前,您已為您的 GraphQL Schema 定義物件類型,但是您尚未定義實際存取該資料的方法。若要執行此操作,您首先需要初始化 Query
類型。
在您的 src/builder.ts
檔案底部,使用 builder
的 queryType
函數初始化 Query
類型
這會註冊特殊的 GraphQL 類型,該類型保存每個查詢的定義,並充當 GraphQL API 的進入點。您在 builder.ts
檔案中定義此類型,以確保查詢 Builder 已定義 Query
類型,這樣您稍後就可以向其中新增查詢欄位。
在此 queryType
函數中,您可以直接新增查詢定義,但是,您將在程式碼庫中單獨定義這些定義,以更好地組織您的程式碼。
將 prisma
執行個體匯入 src/models/User.ts
然後,使用 builder
的 queryField
函數,定義一個 "users"
查詢,該查詢公開您定義的 User
物件類型
以上程式碼片段
- 向 GraphQL Schema 的
Query
類型新增名為"users"
的欄位 - 定義解析為 Prisma Schema 中某些類型的欄位
- 讓 Pothos 知道此欄位將解析為 Prisma Client
User
類型的陣列 - 為此欄位設定解析器函數。
注意:引數清單開頭的
resolve
函數的query
引數。這是 Pothos 在使用prismaField
函數時填入的特定欄位,用於以高效能的方式載入資料和關係。如果您來自 GraphQL 背景,這可能會造成混淆,因為它會變更預期的引數順序。
為了更好地視覺化發生的情況,以下是 Query
類型和 users
查詢,它們將由本節中的程式碼產生
套用 GraphQL Schema
您現在已定義並實作所有 GraphQL 物件類型和查詢。最後需要的組件是一種在單一位置註冊所有這些類型並根據您的組態產生 GraphQL Schema 的方法。
在 src
中建立名為 schema.ts
的新檔案
此檔案將僅匯入模型,導致檔案中的程式碼執行,並執行 builder
執行個體的 toSchema
函數以產生 GraphQL Schema
toSchema
函數產生 GraphQL Schema 的抽象語法樹狀結構 (AST) 表示法。在下面,您可以看到 AST 和 GraphQL 表示法的外觀
在您的 src/index.ts
檔案中,匯入您剛建立的 schema
變數。createServer
函數的組態物件採用名為 schema
的索引鍵,該索引鍵將接受產生的 GraphQL Schema
太棒了!您的 GraphQL Schema 已使用程式碼優先方法定義,您的 GraphQL 物件和查詢類型與您的 Prisma Schema 模型同步,並且您的 GraphQL 伺服器正在提供產生的 GraphQL Schema。
此時,執行伺服器,以便您可以試用 API
執行上述命令後,在您的瀏覽器中開啟 https://127.0.0.1:4000/graphql 以存取 GraphQL Playground。您應該會看到類似於此的頁面
在螢幕的左上角,點擊Explorer 按鈕以查看您 API 的可用查詢和變動
如果您點擊users 查詢類型,螢幕右側將自動填入使用者資料的查詢。
點擊「執行查詢」按鈕以執行該查詢,以查看 API 的運作情況
隨意試用不同的選項,以選擇您想要查詢的欄位以及您想要包含的來自「messages」關係的資料。
摘要 & 接下來的步驟
在本文中,您建構了完整的 GraphQL API。API 是以類型安全的方式建構的,方法是利用 Prisma 產生的類型。這些類型與 Pothos Prisma 外掛程式一起,讓您確保 ORM、GraphQL 物件類型、GraphQL 查詢類型和解析器中的類型都與資料庫 Schema 同步。
一路上,您
- 使用 GraphQL Yoga 設定 GraphQL 伺服器
- 設定 Pothos Schema Builder
- 定義您的 GraphQL 物件和查詢類型
- 使用 Prisma Client 查詢資料
在下一篇文章中,您將透過設定程式碼產生來完成所有工作,以保持前端用戶端和 API 上的類型同步。然後,您將部署您完成的應用程式!
不要錯過下一篇文章!
註冊 Prisma 電子報