讓 GraphQL 在 WordPress 中工作

已發表: 2022-03-10
快速總結↬讓我們探索為 WordPress 提供 GraphQL 服務器的插件。 我們什麼時候應該使用 WPGraphQL,什麼時候應該使用 GraphQL API for WordPress? 是否有一個比另一個有優勢,或者使用其中一個更容易完成的特定任務? 在本文中,我們將一探究竟。

無頭 WordPress 最近似乎很流行,在過去幾週內發生了許多新的發展。 活動激增的原因之一是 WPGraphQL 1.0 版的發布,這是 WordPress 的 GraphQL 服務器。

WPGraphQL 提供了 GraphQL API:一種從 WordPress 網站獲取數據並將數據發佈到 WordPress 網站的方法。 它使我們能夠將通過 WordPress 完成的內容管理體驗與呈現網站分離,為此我們可以使用我們選擇的框架庫(React、Vue.js、Gatsby、Next.js 或任何其他)。

WPGraphQL 中的 GraphQL 客戶端
WPGraphQL 中的 GraphQL 客戶端。 (大預覽)

直到最近,WPGraphQL 還是 WordPress 唯一的 GraphQL 服務器。 但是現在可以使用另一個這樣的插件:由我編寫的 GraphQL API for WordPress。

這兩個插件具有相同的目的:為 WordPress 網站提供 GraphQL API。 您可能想知道:既然已經有了 WPGraphQL,為什麼還要另一個插件? 這兩個插件做同樣的事情嗎? 還是它們適用於不同的情況?

讓我先說一下:WPGraphQL 效果很好。 我沒有構建我的插件,因為它有任何問題。

我為 WordPress 構建了 GraphQL API,因為我一直在研究一個能夠高效檢索數據的引擎,而這恰好非常適合 GraphQL。 所以,然後我對自己說,“為什麼不呢?”,然後我建造了它。 (還有其他幾個原因。)

GraphQL API for WordPress 中的 GraphQL 客戶端
GraphQL API for WordPress 中的 GraphQL 客戶端。 (大預覽)

這兩個插件具有不同的架構,賦予它們不同的特性,這使得使用一個插件或另一個插件更容易實現特定任務。

在本文中,我將從我自己的觀點但盡可能客觀地描述,什麼時候 WPGraphQL 是要走的路,什麼時候 GraphQL API for WordPress 是一個更好的選擇。

跳躍後更多! 繼續往下看↓

使用 WPGraphQL 如果:使用 Gatsby

如果您正在使用 Gatsby 構建網站,那麼只有一個選擇:WPGraphQL。

原因是只有 WPGraphQL 有 WordPress 的 Gatsby 源插件。 此外,WPGraphQL 的創建者 Jason Bahl 直到最近才受僱於 Gatsby,因此我們可以完全相信這個插件會滿足 Gatsby 的需求。

Gatsby 從 WordPress 網站接收所有數據,從那時起,應用程序的邏輯將完全在 Gatsby 這邊,而不是在 WordPress 那邊。 因此,對 WPGraphQL 的任何添加(例如@stream@defer指令的潛在添加)不會產生很大的不同。

WPGraphQL 已經和 Gatsby 需要的一樣好。

在以下情況下使用 WPGraphQL:使用新的無頭框架之一

正如我所提到的,最近在 WordPress 無頭空間中出現了一系列關於幾個新框架和入門項目的活動,它們都基於 Next.js:

  • Colby Fayock 創建了 Next.js WordPress Starter。
  • WebDevStudios 推出了自己的 Next.js WordPress Starter。
  • WP Engine 創建了 Headless WordPress 框架,該框架為其服務提供支持,以託管和部署無頭 WordPress 網站。

如果您需要使用這些新的無頭框架中的任何一個,那麼您將需要使用 WPGraphQL,因為它們都構建在這個插件之上。

這有點不幸:我真的很喜歡 GraphQL API for WordPress 也能夠為它們提供動力。 但要做到這一點,這些框架需要通過接口與 GraphQL 一起操作,以便我們可以交換 GraphQL 服務器。

我有點希望這些框架中的任何一個都能將這樣的接口落實到位。 我在 Headless WordPress Framework 討論板中詢問了它,並被告知可能會考慮它。 我也在 WebDevStudios 的 Next.js WordPress Starter 討論區中提問,但是很遺憾,我的問題立即被刪除,沒有任何回應。 (不鼓勵,是嗎?)

所以現在和可預見的未來都是 WPGraphQL。

如果:使用 Frontity

Frontity 是 WordPress 的 React 框架。 它使您能夠構建一個基於 React 的應用程序,該應用程序通過 WordPress 在後端進行管理。 甚至使用 WordPress 編輯器創建博客文章也是開箱即用的。

Frontity 管理應用程序的狀態,而不會洩露數據的獲取方式。 即使它默認基於 REST,您也可以通過 GraphQL 通過實現相應的源插件來支持它。

這就是 Frontity 的聰明之處:源插件是與數據提供者通信的接口。 目前,唯一可用的源插件是用於 WordPress REST API 的插件。 但是任何人都可以為 WordPress 的 WPGraphQL 或 GraphQL API 實現源插件。 (這是我希望基於 Next.js 的框架複製的方法。)

結論:WPGraphQL 和 GraphQL API 在使用 Frontity 方面都沒有提供任何優勢,而且它們都需要一些初步的努力來插入它們。

在以下情況下使用 WPGraphQL:創建靜態站點

在前兩節中,結論是相同的:使用 WPGraphQL。 但我對這個結論的反應是不同的:雖然使用 Gatsby 我並不後悔,但使用 Next.js 我覺得有必要為此做點什麼。

這是為什麼?

不同之處在於,雖然 Gatsby 是純粹的靜態網站生成器,但 Next.js 可以為靜態網站和實時網站提供支持。

我提到 WPGraphQL 對於 Gatsby 來說已經足夠好了。 這句話實際上可以擴展: WPGraphQL 對於任何靜態站點生成器來說已經足夠好了。 靜態站點生成器從 WordPress 網站獲取數據後,幾乎可以使用 WordPress 解決。

即使 GraphQL API for WordPress 提供了額外的功能,它也很可能不會對靜態站點生成器產生影響。

因此,因為 WPGraphQL 已經足夠好,並且它已經完全映射了 GraphQL 模式(這仍然是 GraphQL API for WordPress 的一項工作),所以 WPGraphQL 是現在和可預見的未來最合適的選擇。

在以下情況下使用 GraphQL API:在實時(即非靜態)網站中使用 GraphQL

現在,如果我們希望 GraphQL 從實時網站獲取數據,例如在為移動應用程序提供動力或在網站上繪製實時數據(例如,顯示分析)或結合靜態和實時方法時,上述情況會發生變化在同一個網站上。

例如,假設我們使用其中一個 Next.js 框架構建了一個簡單的靜態博客,並且我們希望允許用戶向博客文章添加評論。 這個任務應該如何處理?

我們有兩種選擇:靜態實時(或動態)。 如果我們選擇靜態,那麼評論將與網站的其餘部分一起呈現。 然後,每當添加評論時,我們必須觸發一個 webhook 來重新生成和重新部署網站。

這種方法有一些不便之處。 重新生成和重新部署過程可能需要幾分鐘,在此期間新評論將不可用。 此外,如果網站每天收到很多評論,靜態方法將需要更多的服務器處理時間,這可能會變得昂貴(一些託管公司根據服務器時間收費)。

在這種情況下,靜態渲染網站而不使用評論是有意義的,然後從實時站點中檢索評論並在客戶端中動態渲染它們。

為此,建議使用 Next.js 而不是 Gatsby。 它可以更好地處理靜態和實時方法,包括為不同能力的用戶支持不同的輸出。

回到 GraphQL 討論:為什麼我在處理實時數據時推薦 GraphQL API for WordPress? 我這樣做是因為 GraphQL 服務器可以對應用程序產生直接影響,主要是在速度和安全性方面

對於純靜態網站,WordPress 網站可以保密(它甚至可能存在於開發人員的筆記本電腦上),因此它是安全的。 並且用戶不會等待來自服務器的響應,因此速度不一定是至關重要的。

但是,對於實時站點,GraphQL API 將公開,因此數據安全成為一個問題。 我們必須確保沒有惡意行為者可以訪問它。 此外,用戶將等待響應,因此速度成為一個關鍵的考慮因素。

在這方面, WordPress 的 GraphQL API 比 WPGraphQL 有一些優勢

WPGraphQL 確實實現了安全措施,例如默認禁用自省。 但是 WordPress 的 GraphQL API 更進一步,默認情況下禁用單個端點(以及其他一些措施)。 這是可能的,因為 GraphQL API for WordPress 原生提供持久化查詢。

至於速度,持久化查詢也使 API 更快,因為響應可以通過 HTTP 緩存在多個層上進行緩存,包括客戶端、內容交付網絡和服務器。

這些原因使 GraphQL API for WordPress 更適合處理實時網站。

在以下情況下使用 GraphQL API:為不同的用戶或應用程序公開不同的數據

WordPress 是一個多功能的內容管理系統,能夠管理多個應用程序的內容並可供不同類型的用戶訪問。

根據上下文,我們可能需要我們的 GraphQL API 來公開不同的數據,例如:

  • 將某些數據暴露給付費用戶,但不暴露給非付費用戶,
  • 將某些數據暴露給移動應用程序而不是網站。

為了暴露不同的數據,我們需要提供不同版本的 GraphQL 模式

WPGraphQL 允許我們修改模式(例如,我們可以刪除已註冊的字段)。 但是這個過程並不簡單:必須對模式修改進行編碼,並且不容易理解誰在訪問什麼以及在哪裡訪問(例如,所有模式在單個端點/graphql下仍然可用)。

相比之下,用於 WordPress 的 GraphQL API 原生支持這種用例:它提供了自定義端點,可以針對不同的上下文公開不同的數據,例如:

  • /graphql/mobile-app/graphql/website ,
  • /graphql/pro-users/graphql/regular-users

每個自定義端點都通過訪問控制列表進行配置,以逐個字段提供精細的用戶訪問,以及公共和私有 API 模式來確定架構的元數據是對所有人可用還是僅對授權用戶可用。

這些功能直接與 WordPress 編輯器(即 Gutenberg)集成。 因此,創建不同的模式是在視覺上完成的,類似於創建博客文章。 這意味著每個人都可以生成自定義 GraphQL 模式,而不僅僅是開發人員。

我相信,用於 WordPress 的 GraphQL API 為這個用例提供了一個自然的解決方案。

在以下情況下使用 GraphQL API:與外部服務交互

GraphQL 不僅僅是一個用於獲取和發布數據的 API。 同樣重要(儘管經常被忽視),它還可以處理和更改數據——例如,通過將其提供給某些外部服務,例如將文本發送到第三方 API 以修復語法錯誤或將圖像上傳到內容交付網絡。

現在,GraphQL 與外部服務通信的最佳方式是什麼? 在我看來,這最好通過指令來完成,在創建或檢索數據時應用(與 WordPress 過濾器的操作方式不同)。

我不知道 WPGraphQL 與外部服務的交互有多好,因為它的文檔沒有提到它,並且代碼庫沒有提供任何指令的示例或文檔如何創建一個。

相比之下,用於 WordPress 的 GraphQL API對指令有強大的支持。 查詢中的每個指令總共只執行一次(而不是每個字段和/或對像一次)。 此功能可實現與外部 API 的高效通信,並將 GraphQL API 集成到服務雲中。

例如,此查詢演示了通過@translate指令調用 Google Translate API,將許多帖子的標題和摘錄從英語翻譯成西班牙語。 所有帖子的所有字段都在一次調用中一起翻譯。

用於 WordPress 的 GraphQL API 是此用例的自然選擇。

注意事實上,GraphQL API for WordPress 所基於的引擎,GraphQL by PoP,是專門為提供高級數據操作能力而設計的。 這是其鮮明的特點之一。 有關它可以實現什麼的極端示例,請查看“按用戶發送本地化時事通訊”指南。

在以下情況下使用 WPGraphQL:您想要一個支持社區

Jason Bahl 在圍繞 WPGraphQL 凝聚社區方面做得非常出色。 因此,如果您需要對 GraphQL API 進行故障排除,您可能會找到可以幫助您的人。

就我而言,我仍在努力圍繞 GraphQL API for WordPress 創建一個用戶社區,而且它肯定與 WPGraphQL 相去甚遠。

如果您喜歡創新,請使用 GraphQL API

我將 GraphQL API for WordPress 稱為“前瞻性”GraphQL 服務器。 原因是我經常瀏覽 GraphQL 規範的請求列表,並提前實現其中的一些(尤其是那些我覺得有些親近或我可以毫不費力地支持的請求)。

截至今天,用於 WordPress 的 GraphQL API 支持多種創新功能(例如多查詢執行和模式命名空間),作為可選功能提供,並且還有更多的計劃。

在以下情況下使用 WPGraphQL:您需要完整的架構

WPGraphQL 已經完全映射了 WordPress 數據模型,包括:

  • 帖子和頁面,
  • 自定義帖子類型,
  • 類別和標籤,
  • 自定義分類法,
  • 媒體,
  • 菜單,
  • 設置,
  • 用戶,
  • 註釋,
  • 插件,
  • 主題,
  • 小部件。

用於 WordPress 的 GraphQL API 正在逐步將數據模型映射到每個新版本。 截至今天,該名單包括:

  • 帖子和頁面,
  • 自定義帖子類型,
  • 類別和標籤,
  • 自定義分類法,
  • 媒體,
  • 菜單,
  • 設置,
  • 用戶,
  • 註釋。

因此,如果您需要從插件、主題或小部件中獲取數據,目前只有 WPGraphQL 可以完成這項工作。

在以下情況下使用 WPGraphQL:您需要擴展

WPGraphQL 為許多插件提供擴展,包括 Advanced Custom Fields、WooCommerce、Yoast、Gravity Forms。

GraphQL API for WordPress 為事件管理器提供了一個擴展,它會在插件 1.0 版發布後繼續添加更多。

使用 If:為 WordPress 編輯器創建塊

WordPress 的 WPGraphQL 和 GraphQL API 目前都在致力於將 GraphQL 與 Gutenberg 集成。

Jason Bahl 描述了可以進行這種集成的三種方法。 然而,因為它們都有問題,他主張在 WordPress 中引入服務器端註冊表,以便識別 GraphQL 模式的不同 Gutenberg 塊。

用於 WordPress 的 GraphQL API 還具有與 Gutenberg 集成的方法,基於“創建一次,隨處發布”策略。 它從存儲的內容中提取塊數據,並使用單個Block類型來表示所有塊。 這種方法可以避免對建議的服務器端註冊表的需要。

WPGraphQL 的解決方案可以被認為是暫定的,因為它將取決於社區接受使用服務器端註冊表,我們不知道是否或何時會發生這種情況。

對於 GraphQL API for WordPress,解決方案將完全依賴於它自己,而且它確實已經在進行中。

因為它更有可能很快產生一個可行的解決方案,所以我傾向於推薦GraphQL API for WordPress 。 但是,讓我們等待解決方案完全實施(幾週後,根據計劃)以確保它按預期工作,然後我將更新我的建議。

在以下情況下使用 GraphQL API:通過插件分發塊

我意識到:似乎沒有多少插件(如果有的話)在 WordPress 中使用 GraphQL。

不要誤會我的意思:WPGraphQL 的安裝量已超過 10,000。 但我相信這些主要是為 Gatsby 提供動力(以運行 Gatsby)或為 Next.js 提供動力(以運行無頭框架之一)的安裝。

同樣,正如我之前描述的,WPGraphQL 有許多擴展。 但這些擴展只是:擴展。 它們不是獨立的插件。

例如,WooCommerce 擴展的 WPGraphQL 依賴於 WPGraphQL 和 WooCommerce 插件。 如果其中任何一個未安裝,則擴展將無法工作,這沒關係。 但是 WooCommerce 沒有選擇依賴 WPGraphQL 來工作; 因此,WooCommerce 插件中不會有 GraphQL。

我的理解是,沒有任何插件使用 GraphQL 來運行 WordPress 本身的功能,或者特別是為其 Gutenberg 塊提供動力。

原因很簡單:WordPress 的 WPGraphQL 和 GraphQL API 都不是 WordPress 核心的一部分。 因此,不可能像插件依賴 WordPress 的 REST API 那樣依賴 GraphQL。 因此,實現 Gutenberg 塊的插件只能使用 REST 來獲取其塊的數據,而不是 GraphQL。

看起來,解決方案是等待將 GraphQL 解決方案(很可能是 WPGraphQL)添加到 WordPress 核心。 但誰知道這需要多長時間? 六個月? 一年? 兩年? 更長?

我們知道 WPGraphQL 正在考慮用於 WordPress 的核心,因為 Matt Mullenweg 已經暗示過。 但在那之前必鬚髮生很多事情:將最低 PHP 版本提升到 7.1(WPGraphQL 和 GraphQL API for WordPress 都需要),以及對 GraphQL 支持的功能有清晰的解耦、理解和路線圖。

(目前正在開發的全站點編輯基於 REST。那麼在 Gutenberg 的第 4 階段中要解決的下一個主要功能,多語言塊呢?如果不是,那麼它將是哪個功能?)

在解釋了問題之後,讓我們考慮一個潛在的解決方案——一個不需要等待的解決方案!

幾天前,我有了另一個認識:從 GraphQL API for WordPress 的代碼庫,我可以生成一個更小的版本,只包含 GraphQL 引擎,沒有其他內容(沒有 UI,沒有自定義端點,沒有 HTTP 緩存,沒有訪問控制,沒什麼)。 此版本可以作為 Composer 依賴項分發,以便插件可以安裝它來為自己的塊提供動力。

這種方法的關鍵是該組件必須對插件有特定用途,而不是與其他任何人共享。 否則,兩個引用此組件的插件可能會修改架構,從而使它們相互覆蓋。

幸運的是,我最近解決了 WordPress 的 GraphQL API 範圍問題。 所以,我知道我能夠完全確定它的範圍,生成一個不會與網站上任何其他代碼衝突的版本。

這意味著它將適用於任何事件組合

  • 如果包含該組件的插件是唯一使用它的插件;
  • 如果 GraphQL API for WordPress 也安裝在同一網站上;
  • 如果網站上安裝了另一個也嵌入該組件的插件;
  • 如果嵌入該組件的兩個插件引用該組件的相同版本或不同版本。

在每種情況下,插件都有自己獨立的、私有的 GraphQL 引擎,它可以完全依靠它來為其 Gutenberg 塊提供動力(我們不必擔心任何衝突)。

這個被稱為Private GraphQL API的組件應該會在幾週內準備好。 (我已經開始研究它了。)

因此,我的建議是,如果您想在插件中使用 GraphQL 為 Gutenberg 塊提供動力,請等待幾週,然後查看 GraphQL API 用於 WordPress 的弟弟,即 Private GraphQL API。

結論

儘管我確實在遊戲中有所作為,但我認為我已經設法寫了一篇主要是客觀的文章。

我一直誠實地說明為什麼以及何時需要使用 WPGraphQL。 同樣,我一直誠實地解釋為什麼 WordPress 的 GraphQL API 在幾個用例中似乎比 WPGraphQL 更好。

一般而言,我們可以總結如下:

  • 使用 WPGraphQL 實現靜態化,或使用 GraphQL API for WordPress 上線。
  • 使用 WPGraphQL 確保安全,或投資 GraphQL API for WordPress(以獲得潛在的有價值的回報)。

最後一點,我希望 Next.js 框架被重新設計,以遵循 Frontity 使用的相同方法:他們可以訪問接口來獲取他們需要的數據,而不是使用某些特定解決方案的直接實現(當前是 WPGraphQL)。 如果發生這種情況,開發人員可以根據自己的需要——從項目到項目——選擇使用哪個底層服務器(無論是 WPGraphQL、WordPress 的 GraphQL API 還是未來引入的其他解決方案)。

有用的鏈接

  • WPGraphQL:文檔、下載頁面、代碼存儲庫
  • 用於 WordPress 的 GraphQL API:文檔、下載頁面、代碼存儲庫
  • “蓋茨比 WordPress 集成研討會”
    帶有 WPGraphQL 演示的 YouTube 視頻
  • “WordPress 的 GraphQL API 簡介”
    帶有 GraphQL API for WordPress 演示的 YouTube 視頻