原文連接:https://medium.com/@weblab_tech/graphql-everything-you-need-to-know-58756ff253d8前端
原文做者:Weblab Technologygit
譯者:楊濤github
這篇文章的目的是指出GraphQL相關的主要功能和討論特定API規範的優勢和缺點。web
GraphQL一般被描述爲一種"前端導向"的API技術,由於它讓前端開發者以一種比之前簡單得多的方式請求數據。Facebook引入了這種查詢語言,它的目標是以符合直覺和可伸縮的方式定製客戶端應用,以描述數據的先決條件和交互。最好的一點是這種查詢語言不依賴於任何特定的數據庫管理系統,而且獲得了當前數據格式和編碼方式的支持。spring
傳統REST的一個基本問題是,客戶端不能個性化的收集數據。除此以外,運行和控制多個端點(譯者注:表示API的具體網址,也能夠理解爲 接口)是另外一個難點,由於客戶端常常須要從多個端點獲取數據。數據庫
當創建起一個GraphQL服務器,只須要簡單的URL就能獲取和修改數據。所以,一個用戶能夠經過傳遞查詢字符串和聲明他們須要什麼來向服務器請求數據集。後端
在咱們繼續以前,在這你能夠找到咱們的我的實踐。 graphlql-example緩存
說到類似之處,REST和GraphQL都用於構建API。 另外,它們均可以經過HTTP進行管理。 至於差別,REST主要是一個以軟件爲中心的結構化概念,沒有規範,也不求明確的工具集。它更關注API的穩定性而不是性能。 GraphQL,另外一方面,是一種被設計於經過HTTP管理端點,提升性能和適用性的查詢語言。我甚至能夠說,查詢語言和開發web的架構風格放在一塊兒作比較,可能看起來很奇怪:)。一些其餘顯著的不一樣包括:性能優化
毫無疑問,數據獲取是GraphQL的一個最引人矚目的特色之一。經過標準的REST API去生成和獲取數據,咱們可能須要向多個端點發起請求。相比之下,GraphQL提供了能夠獲取服務器數據的單端點bash
query {
books {
id
title
author
isbn
price
}
}
複製代碼
因爲在REST中每一個接口都包含固定的數據格式,相比GraphQL,它會讓你拿到更多的多餘數據。類似的,REST會發送額外的請求去獲取相關數據。 對於上一個例子,GraphQL是很不同的。由於它是一種查詢語言而且支持聲明式獲取數據,用戶能夠從服務器只獲取他們須要的數據。
query {
books {
title
price
}
}
複製代碼
在REST風格中,錯誤管理是很是簡單的。咱們須要作的是檢查HTTP的headers以及瞭解response的位置。經過狀態碼,咱們能快速的找到錯誤和合適的方式去解決它。另外一方面,在GraphQL中,咱們老是收到200 OK的狀態碼。
Request: query { books { error_field } }
Response:
Request Method:POST
Status Code: 200 OK
{「errors」:[{「message」:」Cannot query field \」error_field\」 on type \」Book\」.」,」category」:」graphql」,」locations」:[{「line」:3,」column」:3}]}]}
複製代碼
由於REST強制使用具備緩存機制的HTTP協議,你能夠經過它避免獲取多餘資源。GraphQL,另外一方面,沒有緩存機制,它把緩存的重任交給了用戶。
數據控制會帶來API的邊界,任何的變更都會被視爲一種破壞性的改變,而破壞性改變就須要更新API的版本。這也許就是大多數API選擇版本控制的緣由。若是新API須要最新的版本,咱們就須要頻繁在新API和原有API之間調整。[譯者注:例如接口改變了某個字段的數據類型] 相比之下,GraphQL只返回咱們須要的數據,在不改變原有的請求的狀況下,拿到最新的數據類型和字段。
當使用GraphQL,你能夠方便的棄用一個字段。GraphQL用戶確定會聲明他們須要的字段。
‘author_name’ => [
‘type’ => Type::string(),
‘deprecationReason’ => ‘Deprecated. Use author field’,
],
複製代碼
REST API 以不一樣的方式運做。雖然基本的端點都能在REST API中獲取,但不是全部端點都能返回稀疏字段。[譯者注:便可能包含多餘的字段] 相比之下,GraphQL很是容易監控特定字段的使用。API使用者能在特定的客戶端部署獲取到的字段。
REST的請求默認做爲一個總體,GraphQL一般儘可能發送最少的請求。即使REST的每一個請求返回最基本的部分,相同狀況下,GraphQL能傳輸更多的數據片斷。
和默認採用能讓客戶端和代理端完美的工做的HTTP的REST不一樣,GraphQL以徹底不一樣的方法調用。固然,事情並無像REST同樣簡單,由於你須要調整你的數據集,使用Redis的集合和老是須要祈禱客戶端能緩存。
正如官方文檔解釋的那樣, "在一個基於端點的API,客戶端可以使用HTTP緩存輕易的避免重複獲取資源和識別何時兩個資源是同樣的。客戶端能夠根據API中的URL做爲全局惟一的標識符構建緩存。在GraphQL中,沒有相似URL的對象可以做爲全局惟一的標識符。最佳實踐是提供這麼一個標識符供客戶端使用"
鑑權問題也是咱們在使用GraphQL時關注的一個重要問題。將GraphQL做爲一個特定領域語言考慮,它只是薄薄的一層放置在服務器和客戶端中間。鑑權是單獨的一層,語言自己並不會對應用進行驗證和受權。可是你可使用入口令牌(entry tokens)把客戶端和響應關聯起來。這與咱們在REST中遵循的方法很是類似。
n+1問題是在作GraphQL後端時最明顯的可能遇到的優化問題。
若是你沒有優化你的GraphQL查詢,你可能在一次query進行屢次查詢。沒有合適的緩存和批量處理系統,每次肯定字段的時候服務器都會響應一次請求。DataLoader無疑是最好的解決方案,能夠極大地加強後端的性能,特別是在GraphQL服務器中。 用一個簡單的例子描述n+1問題
query {
users {
name
education {
degree
year
}
age
address {
country
city
street
}
}
}
複製代碼
使用REST API是很容易評估,識別和解決n+1問題的。對於GraphQL有所不一樣。幸運的是,Facebook正在努力經過DataLoader解決這個問題
DataLoader主要使用了批處理和緩存。它用於批量加載客戶端的多個 問題/請求的響應。此外,它能夠緩存響應和讓它們能響應連續相似的資源請求。
好的,咱們已經強調了一些GraphQL重要的方面。可是要開發一個功能齊全的app,咱們也須要知道一些其餘用來加強功能和性能的部分。
正如它的名字,Queries是客戶端從服務端獲取數據。和從多個端點返回詳細信息的REST不同,GraphQL只提供了一個端點,讓客戶端從預約義的框架決定它須要的數據。 例如:
{
Users {
name
}
}
複製代碼
上面的查詢提到的'Users'字段稱爲根字段,其餘數據稱爲載荷。 這個查詢將會返回用戶名的列表:
{
「Users」: [
{「name」: 「Damira」},
{「name」: 「Michael」}
{「name」: 「Salman」}
{「name」: 「Sara」}
{「name」: 「Maria」}
]
}
複製代碼
值得注意的是,這個查詢只返回了用戶名(由於在咱們的查詢中,咱們只聲明瞭咱們須要用戶名)。對於二外的請求,咱們須要爲它增長特定的細節。 例如,假設咱們只但願獲取列表中的最後3個用戶的信息。咱們能夠這麼寫參數來實現它。
{
Users (last: 3) {
name
username
}}
複製代碼
至此,咱們已經看到如何經過查詢從服務器獲取數據。如今讓咱們看一下在GraphQL中建立,省略,更新數據的方法。
Mutations用於建立,更新或者刪除數據。除了須要在開頭增長‘mutation’ 字段,它的結構和queries幾乎同樣。例如,
mutation {
createUser (name : 「John」, username: 」jo123」){
name
username
}
}
複製代碼
Subscriptions用於設置和保存和服務器的實時鏈接。它可讓你獲取相關事件的實時信息。大多數狀況下,客戶端須要訂閱特定的事件來獲取相應的數據。 請經過graphql.org/learn/queri… 獲取詳細信息
在Aollo裏面的Stack 能夠找到一部分問題的解決方案。
若是你有一個正在運行的項目,它是很難快速從RESTful API遷移到GraphQL的。但好消息是你能夠同時享受這兩種方法的好處。 例如你能夠用GraphQL的queries去重構前端裏獲取數據的方式,而後再開始整合 mutations。它容許你緩慢的減小你的controllers裏的actions 此外,你能夠在項目中長時間保持兩種方法並存。例如,若是你想簡化受權機制,你能夠一直用REST架構提供幫助。
https://github.com/weblab-technology/graphql-example
REST and Web Services — In Theory and in Practice — Springer
by Oleksandr Knyga, Software Engineer Maksim Kolesnikov, DevOps Sergei Guliaev, Back-End Developer Viacheslav Eremin, Front-End Developer Sharmeen Hayat, author & Data Specialist Dima Dmytriienko, editor & Brand Specialist
原文提到的GraphQL一些問題,在Apollo GraphQL這個項目中都獲得了必定程度的解決,比加緩存。