英文原版地址:https://www.howtographql.com/...前端
在過去十年中,REST已經成爲設計Web API的標準。它提供了一些偉大的想法,如無狀態服務和結構化資源訪問。然而,基於REST的API太死板,不能知足客戶端快速變化的調用需求。後端
GraphQL的出現是爲了應對更多的靈活性和效率的須要!它解決了與REST API打交道時,開發人員遇到的許多REST的缺點和低效性。數組
爲了說明REST和GraphQL在從API獲取數據時的主要區別,咱們來考慮一個簡單的示例場景:在博客應用中,應用須要展現指定用戶的帖子標題。同一頁面裏還會顯示該用戶的最新3個關注者的名字。 REST和GraphQL是如何解決這個業務的呢?服務器
使用REST API時,一般能夠調用多個接口來獲取數據。針對上述場景,首先能夠調用/user/<id>
接口來獲取用戶數據。緊接着,調用/users/<id>/posts
返回該用戶的全部帖子。最後,第三個接口能夠是/users/<id>/followers
,返回該用戶的關注者列表。網絡
使用REST,必須向三個不一樣的接口發出三個請求以獲取所需的數據。同時你也拿到了額外的數據,由於接口會返回你不須要的其餘信息。前端工程師
另外一方面,在GraphQL中,你只需向擁有數據的GraphQL服務端發送一條查詢語句。服務端就會響應並返回帶有查詢結果的JSON對象。數據結構
使用GraphQL,客戶端能夠精確地指定查詢中須要的數據。 請注意,服務器響應的結構會精確地匹配查詢中定義的結構。函數
REST最多見的缺點之一是不能精準的獲取數據。這是由於客戶端獲取數據的惟一方法是調用接口,而接口老是返回固定數據結構。若是想設計出完美的API,恰好能爲客戶端提供精確的數據,是很是困難的。post
「用圖形的方式思考,而不是端點」。GraphQL共同發明人Lee Byron的Lessons From 4 Years of GraphQL。性能
過多獲取,意味着客戶端拿到了超出真正須要額外的數據。想象一下,在一個頁面中,只須要展現一組用戶名稱列表。但在REST API中,一般會調用/users
接口,來獲取包含用戶數據在內的JSON數組。然而,這個返回結果中可能也包含了用戶的其餘信息,例如。用戶的生日,地址等。而咱們僅僅是想展現用戶名。
另一個問題是獲取的數據不足,而後多發一次請求的問題。獲取不足一般是指接口不能返回所需信息。客戶端將不得再也不次發起請求來獲取數據。可能的場景是,客戶端須要先獲得列表數據,而後爲列表中的每一個元素再次發起請求來獲取元素相關數據。
例如,假設剛纔的應用中,須要展現出每一個用戶的最後三個關注者。 API也提供了接口/users/<user-id>/followers
。爲了可以展現所需的信息,應用須要向/users
接口發起請求,而後針對每一個用戶再去調用/users/<user-id>/followers
接口。
使用REST API的常見模式是,根據應用頁面的須要來設計接口。這樣作很便捷,只要簡單地在客戶端調用對應接口,就能獲取頁面中全部須要的數據。
可是這種模式最主要的缺點是,不容許在前端快速迭代。隨着UI層面的每個改動,接口數據是否匹配,這一點就暴露了很高的風險。所以,後端就須要進行調整,以解決新的數據需求。這會致使生產力降低,特別是下降了將用戶建議快速整合進產品的能力。
若是使用GraphQL,這個問題迎刃而解。得益於GraphQL的靈活性,客戶端的更改不須要服務端有任何額外的工做。客戶端能夠指定其確切的數據要求,所以前端的設計和數據方面的需求變化時,後端工程師不須要進行調整。
GraphQL能夠對請求的數據進行細粒度的分析。因爲每一個客戶端都準確地指定了它感興趣的數據,所以,咱們能夠深刻了解關於數據的使用方式。有了這些信息,就能夠用來優化API,和去除不須要的字段。
使用GraphQL,還能夠對服務器處理請求時,進行低級別的性能監控。 GraphQL使用resolver函數的概念來收集客戶端請求的數據。經過resolver提供的測量和性能數據,能夠爲解決系統中的瓶頸問題提供重要的看法。
GraphQL使用豐富的類型系統來定義API的功能。 API中暴露的全部類型都使用GraphQL模式定義語言(SDL)在Schema中記錄下來。Schema是客戶端和服務端之間的協定,以定義客戶端如何訪問數據。
一旦定義了Schema,在前端和後端工做的團隊能夠在不進行多餘溝通的狀況下開展工做,由於他們都知道經由網絡傳輸的數據的肯定結構。
前端工程師能夠經過mock所需的數據結構輕鬆的進行測試。一旦服務端準備就緒,客戶端能夠快速切換到真正的服務,接着從真正的API加載數據。