GraphQL 的前世此生

GraphQL是什麼

    GraphQL是一種新的API標準,它提供了一種更高效、強大和靈活的數據提供方式。它是由Facebook開發和開源,目前由來自世界各地的大公司和我的維護。GraphQL本質上是一種基於api的查詢語言,如今大多數應用程序都須要從服務器中獲取數據,這些數據存儲可能存儲在數據庫中,API的職責是提供與應用程序需求相匹配的存儲數據的接口。有的人常常把GraphQL和數據庫技術相混淆,這是一個誤解,GraphQL是api的查詢語言,而不是數據庫。從這個意義上說,它是數據庫無關的,並且能夠在使用API的任何環境中有效使用,咱們能夠理解爲GraphQL是基於API之上的一層封裝,目的是爲了更好,更靈活的適用於業務的需求變化。前端

GraphQL出現的歷史背景

    當提起API設計的時候,你們一般會想到SOAP,RESTful等設計方式,從2000年RESTful的理論被提出的時候,在業界引發了很大反響,由於這種設計理念更易於用戶的使用,因此便很快的被你們所接受。咱們知道REST是一種從服務器公開數據的流行方式。當REST的概念被說起出來時,客戶端應用程序對數據的需求相對簡單,而開發的速度並無達到今天的水平。所以REST對於許多應用程序來講是很是適合的。然而在業務愈加複雜,客戶對系統的擴展性有了更高的要求時,API環境發生了巨大的變化。特別是從下面三個方面在挑戰api設計的方式:
1.移動端用戶的爆發式增加須要更高效的數據加載web

Facebook開發GraphQL的最初緣由是移動用戶的增長、低功耗設備和鬆散的網絡。GraphQL最小化了須要網絡傳輸的數據量,從而極大地改善了在這些條件下運行的應用程序。數據庫

2.各類不一樣的前端框架和平臺後端

前端框架和平臺運行客戶端應用程序的異構環境使得咱們在構建和維護一個符合全部需求的API變得困難,使用GraphQL每一個客戶機均可以精確地訪問它須要的數據。api

3.在不一樣前端框架,不一樣平臺下想要加快產品快速開發變的愈來愈難數組

持續部署已經成爲許多公司的標準,快速的迭代和頻繁的產品更新是必不可少的。對於REST api,服務器公開數據的方式經常須要修改,以知足客戶端的特定需求和設計更改。這阻礙了快速開發實踐和產品迭代。前端框架

    GraphQL的出現不只僅是針對開發人員的,Facebook在2012年開始在其native mobile apps中使用GraphQL。但有趣的是GraphQL大部分都是在web技術的背景下使用的,而且在native mobile 領域中只獲得不多的支持。 Facebook第一次公開談論GraphQL是在宣佈開源計劃後不久的2015年React峯會的時候。由於Facebook老是在React的背景下談GraphQL,因此對於沒有React經驗的開發人員來講,要理解GraphQL並非一種僅限於React使用的技術可能還須要一段時間。即使是在這樣的背景下誕生的GraphQL依然是一個快速增加的社區 ,事實上GraphQL是一種技術,能夠在客戶端與API通訊的任何地方使用。有趣的是Netflix和Coursera等其餘公司都在研究相似的想法以提升API的交互效率。Coursera設想了一種相似的技術,可讓客戶指定其數據需求,而Netflix甚至將其解決方案稱爲Falcor。在GraphQL被開源以後,Coursera徹底中止了他們在Falcor上的努力,並轉到了GraphQL的學習上。目前已經有不少的公司在使用GraphQL(https://graphql.org/users/)。服務器

GraphQL和RESTful的區別

前面提到GraphQL能夠理解爲基於RESTful的一種封裝,目的在於構建使Client更加易用的服務,能夠說GraphQL是更好的RESTful設計。在過去的十多年中,REST已經成爲設計web api的標準(雖然只是一個模糊的標準)。它提供了一些很棒的想法,好比無狀態服務器和結構化的資源訪問。然而REST api表現得過於僵化,沒法跟上訪問它們的客戶的快速變化的需求。 GraphQL的開發是爲了應付更多的靈活性和效率,它解決了與REST api交互時開發人員所經歷的許多缺點和低效之處。 爲了說明在從API獲取數據時REST和GraphQL之間的主要區別,讓咱們考慮一個簡單的示例場景:在blog應用程序中,應用程序須要顯示特定用戶的文章的標題。同一屏幕還顯示該用戶最後3個關注者的名稱。REST和GraphQL如何解決這種狀況?網絡

 使用REST API來現實時,咱們一般能夠經過訪問屢次請求來收集數據。好比在這個示例中,咱們能夠經過下面的三步來實現:數據結構

 1. 經過 /user/<id>獲取初始用戶數據

 2. 經過/user/<id>/posts 返回用戶的全部帖子

 3. 請求/user/<id>/followers,返回每一個用戶的關注者列表

調用關係以下圖所示:

 

若是用GraphQL的話,咱們只須要一次請求就能夠完成上述的需求

在GraphQL的世界裏咱們不用多取數據,也不用擔憂數據取少了,咱們只須要按需獲取便可。

REST最多見的問題之一是API的返回數據過多或者過少,這是由於客戶端下載數據的惟一方法是經過訪問返回固定數據結構的endpoint,這就會致使咱們設計API很是困難,由於它既要可以爲客戶提供精確的數據需求,又須要知足不一樣調用者的需求,這自己就是相互矛盾的。GraphQL的發明者Lee Byron提出了一個很重要的概念: 「用圖形來思考,而不是endpoint」

經過上述直觀展現咱們能夠得出一下幾點:

1. 獲取了許多多餘的數據

一般狀況下咱們在調用一個通用API接口時,客戶端獲取的信息比應用程序中實際須要的要多。例如UI須要顯示一個用戶列表,而實際上只須要使用他們的名字。在REST API中一般會調用 /user 這個endpoint,並接收一個帶有用戶數據的JSON數組。可是這個響應可能包含更多關於返回的用戶的信息,例如他們的生日或地址,而這些信息對客戶來講是無用的,由於它只須要顯示用戶的名字。

2. 獲取的數據少於Client所須要的數據

通常來講數據獲取不足意味着某個特定的endpoint 沒有提供客戶端須要的足夠信息,客戶端將須要額外的請求來獲取它所須要的一切。這可能會升級到客戶端須要首先獲取列表信息,而後須要對單條數據添加一個額外的請求以獲取其餘所需的數據,例如考慮其餘Client 也須要顯示每一個用戶的最後三個關注者,該API提供了額外的endpoint  /user/<userid>/followers,爲了可以顯示所需的信息,Client 必須向 /users endpoint 發出一個請求,而後點擊/user/<user-id>/follwers endpoint 來獲取單個用戶的follwers信息。

3. 前端的快速產品迭代對API有很大的挑戰

REST api的一個常見模式是根據你在應用程序內部的展示邏輯來構造endpoint,這很方便,由於它容許客戶端經過訪問相應的endpoint獲取特定視圖的全部所需信息。 這種方法的主要缺點是它不容許前端的快速迭代。對於UI所作的每個更改,如今都存在比之前更多(或更少)的數據的高風險。所以,須要對後端進行調整,以知足新的數據需求,這會下降生產力並顯著下降將用戶反饋集成到產品中的能力。 使用GraphQL這個問題就解決了。因爲GraphQL的靈活性,無需在服務器上額外工做就能夠在客戶端上進行更改。因爲客戶端能夠指定準確的數據需求,因此當前端的設計和數據需求發生變化時,並不須要後端API作出任何的修改就能夠知足展示層的變化。

 4. Schema和類型系統的好處

GraphQL使用強大的Type System來定義API的功能。全部在API中公開的類型都是使用GraphQL schema Definition Language (SDL)在模式中編寫的。該模式充當客戶端和服務器之間的契約,以定義客戶機如何訪問數據。 一旦定義了模式,在前端和後端工做的團隊就能夠在沒有進一步通訊的狀況下完成工做,由於他們都知道經過網絡發送的數據的確切結構。 前端團隊能夠經過mock所需的數據結構來輕鬆測試他們的應用程序。一旦後端API實現完成,就能夠對客戶端應用程序進行切換來調用實際的API獲取數據,這也可使得咱們實現更好的客戶端和服務端的分離。

 咱們能夠看出GraphQL的出現可使得咱們後端API具備更大的靈活性以及擴展性以知足不一樣client對數據的須要,這大大豐富了API的數據提供的能力。 

相關文章
相關標籤/搜索