本文是對 Why we used GraphQL for our API的翻譯,若有侵權等其餘問題,請聯繫筆者刪除。
最近在 Mavel 咱們發佈了 Platform API,咱們想利用整合的力量,將這個力量直接放入天天使Marvel 的人們的創意社區中,所以咱們能更加無縫地工做-與平常服務工具一塊兒工做。react
什麼是一個好的APIweb
若是咱們曾經寫過一個好的 API,首先咱們須要想一想什麼是一個好的 API。所以咱們肯定了設計任何 API 的良好實踐,不管是不是在網絡上。json
即便是最改變生活的工具,我不能發現如何去使用,對於本身而言都是無用的。api
沒必要要的複雜是爲了官僚,咱們老是更喜歡簡單瀏覽器
由於一些事情用你沒有預料的的方式運做,或者由於沒有預料到的反作用被抓到是很差玩的。事情應該儘量的簡單明瞭。服務器
咱們能夠考慮歸檔出這些點做爲開發者體驗。這對咱們是用意義的--當咱們設計app或者web界面,咱們會盡可能去保持用戶體驗。API是針對開發者特定的界面,咱們也應該作一樣的事情。網絡
其餘的APIs哪裏有欠缺app
沒有標準化編輯器
過去五年大多數的web APIs是REST(ish)和json,而不是稍微有點老的SOAP,RPC,或者自定義的XML。一般,這被視爲一件好事,咱們看到了APIs的激增,因爲設備更加智能和服務已經開始更加緊密的協同工做。工具
問題是雖然json已經變成web APIs之間發送數據的標準,可是每一個API因爲其獨一無二的結構和能力,而且沒有標準的方式去描述自身。當每一個API和最後一個不一樣時,沒法構建適合全部的工具。
所以儘管大家正在使用的API或者一些便利的工具,如:編輯器集成工具或者客戶端庫,可能很完美的被良好的文檔支持。
您習慣性地使用的工具可能沒法使用您正在使用的API,或者,若是有的話,過於通用,幫助您解決問題獨特的部分。事實上,這意味着您沒有任何工具。
移動網絡和設備
隨着愈來愈多的網絡流量被過渡到移動設備,產生了另個一個問題。移動端設備位於好延遲低帶寬的不可靠的網絡上。
REST API一般要求客戶端命中多端去收集呈現視圖的多種資源數據(例:在兩個單獨的調用去獲取用戶的配置文件和喜歡的菜單)
由於移動端網絡比其餘網絡更不可靠,所以當發送多個請求的時候失敗的機率更高。這可能使得您獲取到部分數據而不能渲染視圖,或者渲染佔位符當您去從新請求的時候。
與此一樣糟糕的是,網絡延遲是一個大的性能殺手。延遲是兩個設備之間傳送數據的時間,好比您的手機和Marvel的服務器。當設備和服務器之間的延遲是50ms,意味着數據從設備到服務器間傳送須要50ms,RTT(往返時間)是100ms.100ms聽起來不算長,可是您必須考慮到發送單個請求不止一次往返。當您接收數據或者發送數據以前,須要進行DNS查詢,TLS加密握手以及TCP三次握手,這些都須要一次或者屢次往返。咱們使用的在網絡上傳輸字節的TCP協議也須要不斷的確認收到的數據, 確保丟失的包能夠重傳。使人悲傷的是,這些確認遵循物理規律,也須要花費往返時間,
這給整個網路設置了一個上限,它直接與網絡延遲緊密相關。
在高延遲的網絡中,發送一個包往返時間可能須要1s或者更長的時間。網絡延遲極大的超出了app開發者的控制,所以咱們須要減小請求來儘量減小它的影響。
另外一個對移動端不成比例地對移動端設備影響的問題是過分獲取。一般一端返回資源的完整表示,但頗有可能客戶端不必定須要或者想要全部數據,大多數時候須要的是這些數據的子集。儘管如此,服務器仍舊發送無關的數據,而且客戶端對這件事沒有發言權。
從API端點獲取數據的時,頗有可能客戶端不想要或須要返回的全部數據,可是仍舊須要支付傳送和處理的費用,浪費了帶寬和CPU週期,形成更長的響應時間,沒有任何好處。
這些問題的解決方式是什麼
有一些開源項目試圖去解決REST APIs的一些問題,亦即 swagger(OpenAPI)和 API Blueprint。對於swagger 咱們已經有了一點內部經驗(可是不是特別開心,yaml多是地獄),並向咱們現有的API添加新端的時候試用API BluePrint,可是發如今 MSON中的小的錯誤很難被追蹤(並不比yaml好多少)。
儘管這些工具的承諾是很好,他們有一件事情作對了:它們強迫您爲API定義一個模式,這個模式好像是系統邊界文檔同樣,系統邊界一般是最能感覺到集成痛苦的地方。一旦你獲取到一個模式,你能用它作各類各樣酷炫的東西:生成文檔頁面,啓動模擬服務器進行開發,若是你有傾向,甚至能生成客戶端API代碼。由於模式是被標準方式具體化的,所以API構建工具是很容易在使用相同標準的API之間進行移植,由於一切都是提早定義的,你的API消費者確切地知道他們的指望是什麼以及對您的指望是什麼。
這也正是GraphQL作正確的事情,GraphQL定義包含客戶端可用全部數據類型、更改和查詢的模式。這樣每一個人都知道他們的立場。我能馬上確切地明白我能獲取那種操做,它們接受那種類型做爲輸入,返回那種類型做爲輸出。
儘管 swagger和API Blueprint在請求和響應體中攜帶一個模式,可是它們不能處理過分獲取和發送多個請求的問題。若是您將在您的API中解決這些問題,那麼它將是自定義的、非標準的、是單個API獨有的。一般,您最終會爲特定端點編寫視圖。對於前面提到的例子,這意味着有一端會馬上返回用戶和菜單數據。那只是單個視圖,在您的應用中有多少個獨特的視圖?這可能會變得混亂。
那麼爲何是GraphQL
不想REST,GraphQL的核心思想與解決這些問題緊密相關。每次調用僅僅返回在此次請求特定的數據,這有一些好處。首先,徹底經過放在客戶端手中,解決了過分請求的問題。第二,它經過須要客戶端馬上請求它們所須要的數據移除了屢次請求的需求。這種方式的第三個優勢是,它容許咱們做爲API的操做者去確切的查看誰正在請求每一個字段的人,這使得咱們隨着時間的流逝更容易棄用有一些字段,讓新的集成商不去使用,而且返回全部存在的集成的列表,而且與他們取得聯繫提供升級路徑。
正如我前面提到的,工具也是咱們考慮的一個因素,全部上述被說起的解決方案有一些相同的工具和相對健康的社區,可是GraphQL超越了其餘兩個。Gra主要被很是大很活躍的react社區。這意味着大量優秀的工具使得開發者的體驗儘量的好。
好比,鏈接您的編輯器到模式,對您的查詢劃線,在您有機會以前它們以前對錯誤進行標註,將其與自動完成功能相集成,當您輸入的時候,能爲您提供一些建議。
我喜歡的工具之一的是GraphiQL,這是一個爲瀏覽器中運行的GraphQL APIs 構建的IDE。正以下圖您看到的,GraphiQL給您提供編地方去寫查詢(具備您期待的功能:語法高亮,自動補全),查看結果和參考文檔。
它基於瀏覽器意味着咱們可以把它放在任何公共的地方(如Mavel所作的那樣)而且容許某人馬上在友好的開發環境中獲取咱們的API。事實證實是一個有效的方式去控制GraphQL自己以及API的細節,真正地幫助人們開始去運行。
除了它帶來的其餘好處以外,這也是咱們選擇使用GraphQL的緣由,它簡單的運行咱們提供比其它替代方案更好的開發者體驗。