簡介
現代 Web 應用程式需要有效率、靈活的資料擷取。 GraphQL 是一種徹底改變 API 開發的查詢語言,可以滿足這項需求。自 Facebook 2015 年首次亮相以來,GraphQL 的廣泛採用證明了其價值超越了轉瞬即逝的趨勢。
理解 GraphQL 的核心原則
GraphQL 是一種 API 查詢語言和執行階段。與伺服器決定回應結構的傳統 REST API 不同,GraphQL 允許客戶端透過單一請求請求精確的資料。這解決了許多現代應用程式開發挑戰。
想像一下一位知識淵博的圖書館員可以快速找到任何一本書。您無需搜尋多個書架(多個 API 端點),只需提供詳細的請求,圖書館員就會返回您所需要的內容 — 不多也不少。
GraphQL 的模式驅動性質創造了清晰的客戶端-伺服器契約。 每個 GraphQL 服務都定義資料類型,在執行之前啟用模式驗證,以獲得可預測的一致回應。
技術基礎
GraphQL 使用三個主要操作:查詢(資料檢索)、突變(資料修改)和訂閱(即時更新)。 強大的類型系統支援每個操作,定義 API 功能。
<code>type User { id: ID! name: String! email: String! posts: [Post!]! friends: [User!]! } type Post { id: ID! title: String! content: String! author: User! comments: [Comment!]! createdAt: String! } type Comment { id: ID! text: String! author: User! post: Post! }</code>
架構定義關係,允許在單一查詢中進行巢狀資料檢索(例如,使用者的貼文或朋友)。
解析器:GraphQL 的核心
GraphQL 的強大之處在於它的解析器函數。這些函數檢索每個架構欄位的資料。 解析器可以從資料庫取得資料、呼叫其他 API 或執行複雜的計算,所有這些對客戶端都是透明的。
解析器範例(使用 Prisma)
以下是如何使用 Prisma 實作解析器來取得使用者的貼文和好友:
<code>const resolvers = { User: { async posts(parent, args, context) { const posts = await context.prisma.post.findMany({ where: { authorId: parent.id }, orderBy: { createdAt: 'desc' }, }); return posts; }, async friends(parent, args, context) { const friends = await context.prisma.user.findMany({ where: { id: { in: parent.friendIds }, }, }); return friends; }, }, };</code>
這些解析器僅在請求時有效地取得資料。
API 開發的演變
還記得純 REST API 的日子嗎?多個端點傳回固定的資料結構。 這適用於簡單的應用程序,但隨著複雜性的增加而變得笨拙。移動和 Web 用戶端需要不同的數據,導致多次 API 呼叫。
解 N 1 查詢問題
N 1 查詢問題(透過多個資料庫查詢取得相關資料)是一個重大的 API 挑戰。 GraphQL 使用 DataLoader 和類似工具批次和最佳化查詢的能力改變了效能。
實作範例(DataLoader):
取得相關數據常常會導致N 1 問題。 GraphQL 透過 DataLoader、批次和快取資料庫呼叫等工具解決了這個問題:
<code>type User { id: ID! name: String! email: String! posts: [Post!]! friends: [User!]! } type Post { id: ID! title: String! content: String! author: User! comments: [Comment!]! createdAt: String! } type Comment { id: ID! text: String! author: User! post: Post! }</code>
這可以透過批次請求最大限度地減少資料庫查詢,從而顯著提高效能。
真實世界的成功故事
使用 Node.js 和 Apollo Server 實作 GraphQL
這是一個實際的實作:
安裝依賴項:npm install @apollo/server graphql
定義您的架構:
<code>const resolvers = { User: { async posts(parent, args, context) { const posts = await context.prisma.post.findMany({ where: { authorId: parent.id }, orderBy: { createdAt: 'desc' }, }); return posts; }, async friends(parent, args, context) { const friends = await context.prisma.user.findMany({ where: { id: { in: parent.friendIds }, }, }); return friends; }, }, };</code>
<code>const DataLoader = require('dataloader'); const userLoader = new DataLoader(async (userIds) => { const users = await prisma.user.findMany({ where: { id: { in: userIds }, }, }); return userIds.map(id => users.find(user => user.id === id)); }); const resolvers = { Post: { async author(parent) { return userLoader.load(parent.authorId); }, }, };</code>
<code>const typeDefs = `#graphql type Query { hello: String }`;</code>
透過欄位選擇進行效能最佳化 (Prisma)
GraphQL 根據請求欄位最佳化資料庫查詢:
<code>const resolvers = { Query: { hello: () => "Hello, GraphQL!", }, };</code>
這只檢索必要的數據,從而減少開銷。
GraphQL 的未來
graphql-subscriptions
的範例:<code>const { ApolloServer } = require('@apollo/server'); const server = new ApolloServer({ typeDefs, resolvers }); server.listen().then(({ url }) => { console.log(`? Server ready at ${url}`); });</code>
GraphQL 入門
GraphQL 的逐步採用是關鍵優勢。 首先將其與現有 REST API 一起實現,也許作為代理層。這可以在實現優勢的同時最大限度地降低風險。
結論
GraphQL 是資料取得和客戶端-伺服器通訊方面的範式轉移。隨著應用程式的成長,其靈活性和效率變得越來越重要。 考慮使用 GraphQL 來提高效能、開發人員體驗和使用者滿意度。從小實驗開始,逐步擴大用途。蓬勃發展的社區和生態系統現在是將 GraphQL 整合到您的開發堆疊中的理想時機。
參考文獻
作者簡介
Ivan Duarte 是一名自由後端開發人員,熱衷於 Web 開發和人工智慧。
訂閱我們的電子報
直接在收件匣中閱讀 ByteUp 的文章。立即訂閱!
以上是GraphQL 轉變 API 開發的詳細內容。更多資訊請關注PHP中文網其他相關文章!