GraphQL 和 Apollo 爲何能幫助你更快地完成開發需求?

在大前端應用的開發過程當中,如何管理好數據是一件頗有挑戰的事情。後端工程師須要聚合來自多個數據源的數據,再分發到大前端的各個端中,而大前端工程師須要在實現用戶體驗好的視圖 (optimistic UI1) 的基礎上,須要考慮如何管理端上的狀態。前端

clipboard.png

在團隊中使用 GraphQL 可以很好的解決數據管理的痛點。本文接下來會介紹 GraphQL 聲明式(declarative)獲取數據的方法,這將簡化數據管理的難度,而且提高網絡性能。還會介紹 Apollo2 如何經過一系列對開發者體驗好的工具,提升工程師的開發效率。react

譯註1:optimistic UI 是一種 UI 設計模式。例如,你在微信上發送消息會直接顯示,而不用等到消息的網絡請求成功或失敗後再顯示。optimistic UI 的數據管理很複雜,須要先顯示模擬數據,再等待網絡請求成功或失敗後,再顯示真正的數據。經過 Apollo 能夠輕易地實現 optimistic UI。
譯註2:Apollo 是實現,GraphQL 是標準,和 JS/ECMA 的關係同樣。express

開發者體驗

Apollo 能夠幫助團隊更快地實現功能上線,由於它對開發者的體驗很是好。Apollo 目標是"讓各端的數據管理變得簡單"(simplify data management across the stack)。經過 Apollo Client、Apollo Server 和 Apollo Engine,之前須要花上一些功夫實現的功能,好比全棧緩存、數據規範化、optimistic UI,如今變得很簡單。redux

clipboard.png

請求你所要的數據

GraphQL 強類型查詢語言的特性,使得開發者能夠利用牛逼的工具來請求 GraphQL 接口。藉助 GraphQL 內省系統(introspection system),開發者能夠查詢 GraphQL schema 3信息,包括字段和類型。內省系統擁有一些很是炫酷的功能,好比自動生成的文檔、代碼自動補全等等。後端


譯註3:schema 用於描述你所要數據的結構和字段,如:設計模式

{
   dogs {
     id
     breed
     image {
       url
     }
     activities {
       name
     }
   }
 }

GraphQL Playground
Prisma 團隊開發的 GraphQL Playground 工具是一款很是優秀的 IDE,它能夠把自定義的 schema 和查詢歷史自動地生成文檔。只要看一下,你就知道 GraphQL API 中有哪些能獲取到的數據,而不用研究後端代碼或瞭解數據來源。api

GraphQL Playground

Apollo Server 2.0 內置了 GraphQL Playground,更方便你瀏覽 schema 和執行查詢命令。數組

Apollo DevTools
Apollo DevTools 是 Chrome 的擴展程序,能夠查詢 Apollo 的前端緩存(Cache),記錄查詢(Queries)和變動(Mutations)。你還可使用 Apollo DevTools 中的 GraphiQL 來方便地測試前端查詢。緩存

Apollo DevTools

簡化前端代碼

若是你使用過 REST 和狀態管理庫,如 Redux,爲了發一個網絡請求,你須要寫 action creators、reducers、mapStateToProps 並集成中間件。使用 Apollo Client,你不再用關係這些東西。Apollo Client 解決了一切,你只須要專一於查詢,而不須要寫一堆狀態管理的代碼。微信

import ApolloClient from "apollo-boost";

const client = new ApolloClient({
  uri: "https://dog-graphql-api.glitch.me/graphql"
});

有團隊聲稱他們切換成 Apollo Client 後,刪除了上千行狀態管理代碼和一堆複雜邏輯。這得益於 Apollo Client 不只支持遠程數據管理,還支持本地數據管理, Apollo 緩存就是當前應用全局狀態的單一事實來源。

現代化的工具

Apollo platform4 可讓團隊使用現代化的工具,幫忙他們快速發現錯誤、查看 API、開發具備挑戰的緩存功能。

譯註4:Apollo platform 是雲平臺。Apollo 在本文中有兩層含義,首先 Apollo 是 GraphQL 的一個開源實現,其次 Apollo 是開發 Apollo platform 、Apollo Client 、Apollo Server 等產品的公司。

Apollo Engine 是 GraphQL 生態系統中惟一能夠爲你的 API 提供監控和分析的工具。Engine 能夠顯示每一個 resolver5 的埋點指標,能夠幫忙你定位錯誤, 能夠分析 schema 中請求的每一個字段的分佈頻率。 你還能夠將這些數據傳輸到你正在用的其餘分析平臺,如 DataDog,並在某些數據超過報警闕值設置時進行報警。

譯註5:resolver 處理返回字段的函數

Apollo Engine

聲明式數據獲取

使用 GraphQL 的一個主要優勢是它有聲明式數據獲取的能力,不須要前端請求多個接口,不須要手動的聚合數據,只須要你精確地描述你所要的數據,而後 GraphQL 就會將你要的數據返回給你。而使用 REST ,你須要調用每個接口,並過濾出你要的數據,而後將過濾後的數據構形成組件所須要的結構。

GET /api/dogs/breeds
GET /api/dogs/images
GET /api/dogs/activities

REST 的方法不只很差使,並且容易出錯,難以跨平臺重用邏輯。對比一下 GraphQL 聲明式的方式:

const GET_DOGS = gql`
  query {
    dogs {
      id
      breed
      image {
        url
      }
      activities {
        name
      }
    }
  }
`;

在上面,咱們定義了咱們想要從服務端獲取的對象的結構。GraphQL 負責組合和過濾數據,同時返回咱們想要的數據字段和結構。

如何使用 GraphQL 查詢?Apollo Client 構建了 GraphQL 聲明式請求數據的方法。在 React 應用中,獲取數據、跟蹤加載和錯誤狀態以及更新 UI 的全部邏輯,都封裝在一個 Query 組件中。這種封裝方式使數據獲取組件和展現組件很容易的組合在一塊兒。讓咱們看看,如何在 React 應用中使用 Apollo Client 獲取 GraphQL 數據:

const Feed = () => (
  {/* 數據獲取組件 Query*/} 
  <Query query={GET_DOGS}>
    {/* 展現組件:由 Error、Fetching、DogList 等組成的函數組件 */}
    {({ loading, error, data }) => {
      if (error) return <Error />
      if (loading || !data) return <Fetching />;
    
      return <DogList dogs={data.dogs} />
    }}
  </Query>
);

Apollo Client 管理整個請求的週期,從請求開始到請求結束,包括爲你跟蹤加載和錯誤狀態。這裏不用設置中間件,不用寫模板代碼,不用重構的數據結構,不用關心請求緩存。你所須要作的就是描述你組件要的數據,而後讓 Apoolo Client 去完成那些繁重的工做。

當你使用 Apollo Client 時,你會發現你能刪除不少不須要的數據管理方面的代碼。具體可以刪除多少行代碼,要根據你項目的狀況來判斷,但有些團隊聲稱他們刪除了數千行代碼。要了解更多 Apollo Client 的牛逼功能,例如 optimistic UI、從新獲取、分頁獲取,請查看咱們的狀態管理指南。

提高網絡性能

在許多狀況下,在現有的 REST 接口層之上增長 GraphQL API 層,能夠提升你 App 的網絡性能,特別是在網絡差的狀況下。雖然,你應該經過網絡性能監控來衡量 GraphQL 如何影響你的 App,但你們一般認爲 GraphQL 經過避免客戶端與服務端的往返通信(round trips),和減小請求數據的大小來提高網絡性能的。

更少的請求數據

由於從服務端返回的響應中只包含你指定的查詢數據,因此 GraphQL 相對於 REST 能夠顯著地減小請求數據的大小。讓咱們看看前面文章中的例子:

const GET_DOGS = gql`
  query {
    dogs {
      id
      breed
      image {
        url
      }
      activities {
        name
      }
    }
  }
`;

GraphQL 服務響應中只包括 dogs 對象的 id、breed、image、activities 字段,即使 REST 層的接口 dogs 是帶有 100 個字段的對象也是如此,全部多餘的字段都將在返回給客戶端以前過濾掉。

避免往返通信(round trips)

因爲每一個 GraphQL 請求只返回一個響應,使用 GraphQL 能夠幫助你避免客戶端到服務端的往返通信。使用 REST,請求一個資源就是一次往返通信,往返通信會快速地增長。若是你請求要列表中的每一項,每一項都須要一次往返,每一項中的每一個資源也須要一次往返,總次數就是兩者的乘積6,這就致使了請求時間過長。

譯註6:極端 REST 例子,列表長度 N,每一項 3 個資源,請求次數就是 3*N

GET /api/dogs/breeds
GET /api/dogs/images
GET /api/dogs/activities

使用 GraphQL,每一個查詢表明一次往返通信。若是你但願進一步的減小往返,你能夠實現查詢批處理(query batching),將多個查詢封裝到單個請求中。

產品案例

雖然 GraphQL 規範是由 Facebook 在 2015 年公佈的,可是自 2012 年以來,GraphQL 就是 Facebook 移動應用開發的重要組成部分。

在 Apollo 團隊,咱們發現 GraphQL 爲咱們現有方案中遇到的不少問題提供了出色的解決方案,如今咱們用它來優化咱們的技術基礎設施。幾年來,咱們和開源社區、客戶、合做夥伴一塊兒,爲開源項目 Apollo 帶了了諸多創新。咱們很驕傲,Apollo 適用於各種公司,從創業公司到大型企業。

除了咱們本身的經驗,咱們還收到了積極地在生產環境中使用 Apollo GraphQL 的企業客戶的普遍反饋、貢獻和支持。一些最值得借鑑的案例是:

相關文章
相關標籤/搜索