繼全面采用Node.js以后,PayPal分享大幅度踩坑GraphQL心得 - Mark Stuart

19-10-31 banq
                   

這篇文章涵蓋了我們在PayPal擴展GraphQL時學到的所有知識,并將作為在您的公司中部署GraphQL的指南。

一年前,我們撰寫了“?GraphQL:PayPal Checkout的成功案例?”,其中涵蓋了我們從REST到批處理REST到GraphQL的歷程。從那以后很多事情改變了!這篇文章是我們在PayPal?構建GraphQL?API時獲得的一系列最佳實踐和觀察的一部分。

一年前,使用GraphQL的產品很少。雖然我們在PayPal Checkout上取得了成功,但沒有基礎架構,工具,培訓或支持。盡管存在這些差距,但GraphQL仍然像火箭一樣起飛。在撰寫本文時,我們有50個使用GraphQL的不同產品!

采用速度很快,像其他技術變革一樣,企業級擴展與水平擴展或為服務器或云計算支付大量資金無關。擴展人員,工具和流程是最具挑戰性的。

向內看

在部署GraphQL之前,重要的是要深入了解自己的公司,并反思自己是誰,干什么的以及優點和缺點是什么。

在PayPal,我們的產品使用JavaScript構建。后端使用Node.js對前端進行響應。堆棧中還有數百個Java REST服務和一些類似于C ++ SOAP的服務。

PayPal是最早使用Node的公司之一,并通過NodeDay之類的活動以及與Node FirmNodeSource的合作幫助啟動了“企業中的Node”品牌。

PayPal在2013–2015年期間遷移到了Node。它改變了整個公司,并改善了我們制造和運輸產品的方式。一個C ++單體應用程序簡單的內容更改將需要數周時間才能部署。現在,開發人員可以在幾分鐘內進行試驗,迭代和推出新產品功能。

那不是一夜之間發生的,不是偶然的。在Node加入PayPal之前,Bill Scott提出了使用LeanUX構建產品的愿景,其中迭代和學習是關鍵。在LeanUX中,UI位是實驗性的并且是一次性的。如果實驗效果不佳,請不斷進行迭代!Node.js是成功的關鍵。

2014年,我們推出了Kraken,這是Express之上的一組庫,旨在通過可配置的中間件,安全性默認設置,dust.js渲染器和內容本地化為您的應用“提供一些幫助”。現在,團隊正在構建客戶端React應用程序,而應用程序是部署到CDN的靜態文件包,而不是在服務器群中運行的代碼。

對于API,我們使用BFF(backend-for-frontend)模式。盡管它們非常專業,并且允許開發人員進行迭代,但是它們緊密耦合并且不能很好地重用。結果是我們有很多團隊反復迭代和構建相同的事物!構建BFF API也不是一件容易的事。通常,它們包含許多編排邏輯,在這些邏輯中,您需要從5、10、15個不同的服務中獲取數據,對這些響應進行規范化,丟棄95%的響應,然后將數據映射,過濾和分類為所需的數據。編寫此代碼并不能很好地利用我們的開發人員的時間。這種緊密的耦合和缺乏重復使用對我們來說是一個問題。

GraphQL可以提供幫助嗎?是!

開發人員經驗>性能

在跳入生產就緒項目清單之前,我們應該重新設定期望值。當您初次接觸GraphQL時,通常會想到主要的好處是通過網絡傳輸較少的數據,從而可以實現更快,更高性能的應用程序。

大型公司將GraphQL置于現有REST服務之上。結果是您的GraphQL查詢將僅與最慢的REST服務一樣快。GraphQL允許您在一次往返中獲取所需的一切。如果客戶端和服務器之間存在空閑,則可以減少往返行程并減少延遲。但是,這并不是您可以為每個人做出的承諾。

一段時間后,您將意識到開發人員?經驗和靈活性的好處遠比性能引人注目。

GraphQL對人類友好。使用GraphQL,開發人員可以根據字段而不是端點,域或復雜聯接來考慮。開發人員可以遍歷該圖以選擇用戶的名字,60x60的個人資料照片,主要送貨地址和信用卡,而不必調用6-10種不同的服務。新員工都喜歡它。如果您知道JSON是什么樣子,請刪除雙引號和逗號,然后就可以查詢GraphQL API。您的UI開發人員喜歡它,因為它以產品為中心,具有聲明性,并具有豐富的工具集,可減少集成摩擦并提高信心。

當您將GraphQL推薦給公司的領導者和團隊時,請關注開發人員的經驗,生產力和靈活性。否則,您可能會讓他們失望。

GraphQL位于堆棧邊緣

在PayPal,我們的核心服務由獨立的后端團隊開發,我們的產品團隊構建BFF API,以從這些基礎核心服務中整理數據。最初,我們認為“ GraphQL應該無處不在”!

經過大量的實驗和反思,我們發現GraphQL在堆棧的邊緣發光最多

GraphQL以產品為中心,應該受到您的產品團隊的影響(或開發)。GraphQL模式應在設計時首先由產品團隊提供意見。后端開發人員不應孤立地設計它們。GraphQL做得很好。因此,GraphQL最適合您的堆棧邊緣,并且可以與REST協同工作。

在公司啟用GraphQL

好的,是時候實現這個了!本部分是在貴公司啟用GraphQL的清單。

首先,您需要為產品團隊奠定基礎。GraphQL新穎且令人興奮,有許多開放式問題和見解。幾乎沒有什么是一成不變的。您有很多選擇!

  • 誰是您的API開發人員和消費者?
  • 誰來貢獻?他們知道什么語言?
  • 他們今天如何構建API?它們是專門用途還是通用用途?
  • 您要使用現有的框架和工具嗎?哪個?
  • 您需要添加公司特定的內容嗎?身份驗證,授權,重試,斷路器,自定義HTTP狀態代碼,錯誤處理?
  • 您將如何執行標準?
  • 您將如何處理錯誤?

建立基礎

在PayPal,GraphQL已與為BFF API和UI做出貢獻的產品團隊脫穎而出。我們為GraphQL API使用Node.js。與許多其他公司一樣,我們使用Apollo開源庫和工具Apollo擁有專門的團隊來構建和維護這些工具,因此它們在一流的文檔編制方面是一流的。我們使用apollo服務器,并在特定于PayPal的生產就緒狀態下投入使用,例如日志記錄和檢測,身份驗證,錯誤處理和速率限制。

如果您有任何獨特的要求,請創建可與開源庫(例如Apollo)一起使用的模塊和插件。不要創建深層抽象或向開發人員隱藏復雜性。保持它可用于Google!

請記住,GraphQL仍然是一個API。您將要確保具有足夠的日志記錄,重試,斷路器模式,速率限制查詢復雜性檢查。

擴展知識

確保架構師和API設計人員支持GraphQL,以幫助您擴展設計審查并執行標準。他們很可能已經設計了REST API多年。GraphQL是不同的。起初,您可能會遇到阻力。推動它。您需要花時間與他們一起概述差異,并挑戰它們以不同的方式進行API設計:沒有版本控制,擁抱圖表而不是使用ID創建關系,沒有HATEOAS鏈接。通過邀請架構師,您將不會是唯一的主題專家,它將為GraphQL帶來合法性。

制定標準

您需要設定一些設計標準。創建一個文檔并在任何地方引用它。使用諸如graphql-schema-linter之類的工具來強制命名約定。

一些示例包括:

  • 所有字段都必須有描述或注釋
  • 類型取名:LikeThis,字段取名:LikeThis。枚舉值:LIKE_THIS
  • 盡可能使用枚舉
  • 棄用的字段必須有原因
  • 沒有集合或列表后綴。(例如:使用cards,而不是cardList)
  • 偏好具有引起狀態變化的輸入類型

然后,您將需要圍繞分頁進行選擇。在架構中顯示列表的首選方式是什么?基于游標的分頁

您將如何發現錯誤?在撰寫本文時,我們錯誤處理還沒有弄清楚,有很多選項可供選擇:

  • 使用默認錯誤數組
  • 使用自定義屬性擴展錯誤
  • 模式中的錯誤字段
  • Union types

在PayPal,我們選擇使用自定義屬性擴展錯誤。我們喜歡它仍然符合規范,并允許我們在需要時向錯誤添加錯誤分類和其他元數據。我們認為其他選項無法實現,并且允許錯誤不被注意到。我們將在以后的中型帖子中提供更多詳細信息。

認證/授權

首先,我們保護了整個架構,然后意識到我們擁有許多具有不同特權的不同類型的用戶。然后,我們創建了一個高階auth函數,您可以使用它包裝解析器。最后,我們意識到創建自定義auth指令是保護架構的最佳方法。

通過出色的工具獲得超能力

之前,我們撰寫了《GraphQL:檢測您的API和釋放超能力》,它解釋了GraphQL與REST相比有何獨特優勢,您可以更好地了解API的使用方式,并在與API集成并保護客戶端的過程中為客戶提供額外的信心應對重大變化。

對于初學者,您可以將延遲,錯誤和使用情況數據通過管道傳輸到公司的監控儀表工具。

我們建議使用的其他工具包括:graphql-playground用于測試開發模式下的查詢,graphql-schema-linter用于強制執行模式命名約定,eslint-plugin-graphql用于對模式查詢客戶端查詢,graphql-doctor用于PR狀態檢查。

Apollo?Graph Manager提供的儀器工具可顯示現場級別的深刻見解,對突破性變化的信心,列入白名單的查詢,并通過為每個字段提供襯布和在線SLA計時來簡化客戶集成。

Apollo?Graph Manager不是免費的。我們可以自己建造嗎?也許可以,但不會那么完美。我們沒有GraphQL基礎架構團隊。如果我們這樣做了,我們就不想等待12-18個月來構建可比較的東西并必須對其進行維護。我們現在想兌現GraphQL的承諾!從購買與構建的決策來看,Apollo Platform是一個明確的購買。我們建議您也考慮一下。

在企業中擴展GraphQL面臨的挑戰

到目前為止,GraphQL很棒,但是直到我們解決了它的組裝方式和成功度的一些問題之前,它才是很棒的。

在2012年之前,PayPal是C ++ monorepo。從那時起,我們在許多領域和產品團隊中產生了數千個GitHub存儲庫,構成了服務和應用程序層。對于擁有monorepos的Facebook和GitHub這樣的公司來說,共享并不是什么大問題。

GraphQL在許多存儲庫中都很棘手。如果沒有諸如自定義遠程類型之類的自定義技巧,就無法引用或鏈接本地文件系統中不存在的遠程類型。開發人員發現或重用其他服務中定義的類型并不容易。

組裝GraphQL

用戶希望看到一個可以瀏覽的單個內聚圖,而無需考慮許多服務,而必須使用許多服務來獲取所需的數據。實際上,組裝單個圖形是困難的。

一種解決方案是模式拼接,其中網關使用底層GraphQL API的模式并向開發人員顯示單個模式,并將傳入的查詢委派給底層API。Marc-Andre Giroux寫了一篇出色的文章,介紹了模式縫合的挑戰。通過模式縫合,網關具有粘合代碼,負責維護類型之間的關系并確保正確執行子查詢。該膠水代碼是有問題的,當網關所有者不知道這些類型的,當它是不現實的產品團隊擁有這些基礎設施之間的關系。

Apollo Platform的解決方案是一種聯合開發范例,該范例使用自定義指令以聲明方式將類型鏈接在一起。它消除了網關中對粘合代碼的需求,設置了適當的關注點分離,并允許您擴展在本地開發中不擁有的類型。看看公司是否會采用它以及聯盟將如何影響GraphQL規范將很有趣。

如果構建一張圖不切實際怎么辦?在貝寶,我們為快速迭代和持續學習進行了優化。許多開發人員沒有動力放慢腳步,達成共識并成為更大整體的一部分。這是我們文化的雙刃劍。如果無法繪制一張圖,我們還可以如何重用工作?另一個選項是帶有GraphQL Modulesgraphql-component之類的選項的本地模塊。使用本地模塊,您可以選擇所需的類型和字段,并且所有代碼都在同一進程中運行。模式縫合和聯合的許多問題都消失了。但是,我們有大量類似的端點,并且服務器的占用空間并未減少。這個可以嗎?

這是我們使用GraphQL遇到的最困難的問題。

(banq注:業務聚合問題能通過GraphQL反復組合解決嗎?)

?

                   

1
美女漫画大全