什麼是 GraphQL?

如題,跟 MySQL、NoSQL 什麼關係?


一個解決「前端做還是後端做」問題的工具。


graphql 說白了就是把一個數據呈現應用裡面,構造資料庫查詢的鍋由後端API丟給了客戶端前端的框架。

如果你寫過那種純粹呈現數據的客戶端就知道,前端經常要和後端溝通好,我要呈現哪些數據,給你ABCD幾個參數要EFGH這幾個結果欄位,然後後端同學加一個API叫getXxxx,接受你提供的幾個參數,自己構造好資料庫查詢,然後把查詢結構轉換成前端想要的json格式發回去。

如此看來,前端只要調用後端的API,拿到數據刷新到UI上就行了,所有的數據準備工作都是後端負責的,這樣好嗎?不好,前後端需要對數據的格式和請求方式溝通,理解出了偏差,修改也不方便,前端呈現數據需要臨時加一個欄位,還得去麻煩後端去改代碼。

所以,graphql就是一個能讓你在前端構造數據查詢的東西,前端想要什麼,自己構造查詢語句,自己規定結果做成什麼格式,查詢發給後端,後端只要把原生的表結構丟給graphql就好了。

甩鍋甩鍋無窮盡也


沒有關係,QL = Query Language, 是查詢語音的簡稱,但它其實是一種規範~ 更多的是類比於 RESTful API。正好最近總結了一篇文章,暫時粘貼過來~

GraphQL 淺談,從理解 Graph 開始

前言

GraphQL is a data query language developed internally by Facebook in 2012 before being publicly released in 2015. It provides an alternative to RESTful architectures. —— from wikipedia.

GraphQL 是 Facebook 於 2012 年在內部開發的數據查詢語言,在 2015 年開源,旨在提供 RESTful 架構體系的替代方案。

掘金翻譯計劃在今年 10 月上線了 GraphQL 中文官網,最近它的討論和分享逐漸增多。其實阿里內不少業務線早有嘗試和分享,聽聞基於 GraphQL 再造了個 TQL。也在其開源的Node.js企業級框架egg中,發布了對應的 plugin。感覺這是一個讓廣大(前端)開發者(重新)認識學習GraphQL的好機會,就讓我們來回顧一下它~

從 Graph 字面開始

先看官網的解釋~

GraphQL 既是一種用於 API 的查詢語言也是一個滿足你數據查詢的運行時。

總結的稍顯高深,簡單拆解一下:

SQL (Structured Query Language) 是結構化查詢語言的簡稱。所以Graph+ QL =圖表化(可視化)查詢語言,是一種描述客戶端如何向服務端請求數據的API語法,類似於 RESTful API 規範。

註:不要聯想到 MySQL、NoSQL,它不是圖形資料庫,比如 Neo4j。

GraphQL 有配套的資料庫服務, graphcool 可以部署在 Docker 上或運行在基於 BaaS(Backend as a Service) 的 Graphcool Cloud。但它不依賴任何資料庫,且能和任何後端(SQL、MongoDB、Redis 等)一起使用,也可以包裹在 RESTful API 之上。

GraphQL 的特性

它定義了一套類型系統(Type System),類似於持續演進(相互借鑒)的FlowTypeScript,用來描述你的數據,先看官網的例子(細節再議)

項目的type
type Project {
name: String
tagline: String
contributors: [User] // 數組表示多個,type 為下面的 User
}
type User {
name: String
photo: String,
friends: [User] // User 的朋友們, type 還是 User
}

接下來你可以把GraphQL查詢語言(Queries)當成是沒有值只有屬性的對象,返回的結果就是有對應值的對象,也就是標準的JSON

請求你所要的數據 // 基於 Queries
{ // 查找 name 為 GraphQL 的 project
project(name: "GraphQL") {
tagline
}
}
得到可預測的結果
{ // 返回 json
"project": {
"tagline": "A query language for APIs"
}
}

雖然 project 在類型系統里定義了三個欄位,但我們(客戶端)只需要 tagline 這個欄位,服務端就只返回這個欄位,而 contributors 里的 User 和其對應欄位,本次查詢(Query)並不關心。這個 demo 看似簡單,其實帶來了很多特性~

  • 強類型GraphQL與 C 和 Java 等後端語言相得益彰,服務端能對響應的形狀和性質做出一定保證,而RESTful是弱類型的,缺少機器可讀的元數據;
  • 分工GraphQL讓服務端定義好支持哪些Queries,把對數據的Query需求下放到客戶端管理,分工明確的同時保持對 API 的聚焦;
  • 分層GraphQLQuery本身是一組分層的欄位,查詢就像返回的數據一樣,是一種產品(工程師)描述數據和需求的自然方式;(PS:部分翻譯的,國外好像都把產品叫做 Product Engineers 而不是 Product Manager。感覺在吐槽的樣子)
  • 預測性GraphQLQuery只返回客戶端要求的內容,沒有任何冗餘(不浪費流量),而且它只有一個介面地址,由此衍生了另一個特性;
  • 兼容性:需求變動帶來的新增欄位不影響老客戶端,服務端再也不需要版本號了,極大簡化了兼容問題;(App 通常是 1-2 周的固定周期發版,在原生應用不強制升級的世界裡,會出現用戶 1-2 年都不升級的情況。 這意味可能同時有 52 個版本的客戶端查詢我們的服務端,而在 Fackbook 中 GraphQL API 曾支持了橫跨 3 年的移動端)
  • 自檢性GraphQL能在執行Query之前(即在開發時)提供描述性錯誤消息,在給定查詢的情況下,工具可以確保其句法是正確有效的,這使得構建高質量的客戶端變得更加容易;
  • Doc MockGraphQL的文檔永遠和代碼同步,開發無需維護散落多處的文檔,調用者也無需擔心過期問題,而且基於類型系統的強力支撐和 graphql-tools,mocking 會變得無比容易。

GraphQL通過它的特性解決了不少問題,當然它不是沒缺點的,這個下期再聊~

我的觀點:當技術棧的缺點因其演進不再明顯之時,必是它優點大放光彩之日 。與此同時GraphQL伴隨著 graph 又帶來了很多新的思考~

GraphQL 的延伸,graphical graph(s)

圖像天然更生動形象易於理解,這意味著GraphQL交互極強的工具和生態,比如:

  • graphiql —— A graphical interactive in-browser GraphQL IDE. 一個讓我們在瀏覽器里用圖形交互的方式探索及書寫GraphQL的 IDE。
  • graphql-voyager —— Represent any GraphQL API as an interactive graph. It"s time to finally see the graph behind GraphQL! 用互動式圖表展示任意的 GraphQL API,總算能看見GraphQL背後的 graph 了!

今年 5 月 22 日 GitHub 發文宣布,去年推出的 GitHub GraphQL API 已經正式可用 (production-ready),並推薦集成商在 GitHub App 中使用最新版本的GraphQL API V4。我們可以用 graphql-voyager 探索(但因 Types、Queries、Mutations 較多數據載入略慢)。

後一個工具可把筆者驚艷壞了,想了解它的生態可以在 awesome-graphql 里尋找。通過它們,所有人都能快速閱讀查詢文檔,調試我們的查詢。

PS:主要是方便調用者和團隊新人的,不過可以思考一個問題,每天是寫代碼還是看代碼多?看介面文檔呢?

另一種思維模式 —— Thinking in graphs

圖是將很多真實世界現象變成模型的強大工具,因為它們和我們天然的心理模型和基本過程的口頭描述很相似。大家應該都沒忘在學校做的資料庫設計,筆者簡單回顧下當年手繪 E-R 圖的過程

  • 一個班級有一個班主任,1:1的關係;
  • 一個班級有多學生多個教師,1:n的關係;
  • 每個學生可以上不同的課程,n:m的關係。

OK,然後大概就成了下面這個樣子,原諒我從百度找的圖:

E-R 圖也稱實體-聯繫圖(Entity Relationship Diagram),提供了表示實體類型、屬性和聯繫的方法,用來描述現實世界的概念模型。

  • 真實世界的數據在本質上是分層的:今天大多數的產品開發涉及視圖層次的創建和操作,這與應用程序的結構保持一致;
  • 我們的開發模式本身也是產品需求驅動的,客戶端關注需求(怎麼取、取哪些),服務端關注能力(可用性、性能),這樣的協作模式更現代更高效;
  • 數據和實體背後的本質也是關係圖:我們的服務端用對象和關係的形式處理,只不過在資料庫用扁平的表格存儲它們;(以前你可以將負責的業務數據通過導出 E-R 圖展現給同事和老闆。如今你還可以通過GraphQL把到對外暴露的API也建模成一張圖。)
  • GraphQL沉澱出來的數據模型(Schema)也可以作為一種給你的團隊(後端前端客戶端甚至產品)及第三方溝通的共同語言,讓大家對這些業務領域的規則形成共同的理解,最終達成共識。

GraphQL的原理、和RESTful的優劣對比以及最佳實踐等等,未完再續~

參考資料 —— 需要翻牆

來自官方的介紹:

GraphQL Introduction

GraphQL: A data query language

來自 InfoQ 的採訪:Facebook開源數據查詢語言GraphQL

來自官方的 Talks:GraphQL: Designing a Data Language

30分鐘內現場演示用Python、Ruby、Nodejs.js,設計3次 GraphQL Sever:Zero to GraphQL in 30 Minutes


Graphql只是一種用於 API 的查詢語言!!!!

Graphql只是一種用於 API 的查詢語言!!!!

Graphql只是一種用於 API 的查詢語言!!!!

它做的事情只是能夠準確的獲得你想要的數據!

當然這只是做的事情我已經感覺很強大了

最重要的是!

它可以做到用一個請求能獲取你所需要的所有數據,和以往我們用REST API(以前我們要多個數據就要好多URL)不同!

其他的需要自己去用才能體會Graphql的魅力!

下面提供一些我收藏的網站或者說教程:

  • 印記中文翻譯的網站: Graphql
  • Graphql的視頻教程官方: How to Graphql
  • 強烈推薦Apollo: Apollo Graphql
  • Graphcool!
  • 這是一個學習apollo的github項目: learn apollo

老爺們覺的有用可以給個贊么么噠!


謝邀。大家都回答得差不多了額,我用簡單的話說說吧。

GraphQL主要是作用於數據介面,比如前端後端交互。是給客戶端篩選自由獲取服務端事先定義好的數據,提高了交互介面的靈活性。這些數據是從MySQL、NoSQL的庫裡面查出來,這就是關係吧。GraphQL本身不是資料庫(知道這點就知道區別了),貌似也不具備聚合計算數據功能(這點我不確定),也不會直接操作資料庫。

簡單例子,後端使用了GraphQL之後,資料庫查出來A,B,C,D四個欄位,客戶端需要數據的時候,你可以隨意使用這四個欄位的各種組合,只要A,C欄位還是只要A,C,D欄位等等,不再需要和服務端交流。

MySQL、NoSQL之類核心是為了儲存數據,有儲存自然有取出數據的查詢。這是和GraphQL最主要功能區別。

簡化後,GraphQL可以理解成一個靈活的ajax介面,mysql可以理解成一個儲存數據的文件。最本質的區別。


我在上家公司做Facebook H5 APP時一直在用這套東西

你可以理解成另一種寫法的SQL

Facebook開發者有個GraphQL的工具很方便

https://developers.facebook.com/tools/explorer/145634995501895/


思考graphql到底是什麼東西之前,可以類比思考圖資料庫是什麼?

以知乎為例,用圖資料庫的理論,其實就只有節點和關係。節點比如說用戶,問題,文章等。關係比如說回答,點贊等。如果知乎使用圖資料庫neo4j存儲,那查詢一個用戶回答了什麼問題,或者查詢誰點贊了某篇文章是不是天生的非常簡單?

可是大家應該知道,知乎的數據是MySQL嘛。查詢的時候,這裡面涉及了大量的join。為了加速,就要建索引,做緩存。是不是?

那麼人的思考方式是怎樣的呢?比如查下某個用戶超過100點贊的問題。我們在思考的時候,我們並不需要它的具體存儲方式。無論如何存這個表述是成立的。因為用戶回答了問題,問題獲得點贊,點贊是一種關係。

所以說sql的問題是什麼?因為人對查詢的表述,是脫離實際存儲結構的抽象存在,而sql其實還需要考慮實際表的設計。所以說,從表達的層面,我們需要更抽象的方式。

類似這樣:

user(30)

questions(support &>100)

其實就是圖的關係。當然上述不是graphql,而是一種類似的表達,這種表達忽略了存儲結構,是一種更抽象的語意。也更加容易寫,也更強大。

寫這樣的語法當然比寫sql省事嘛,對不對?這才是我們思考的語意,對不對?好了,現在問題來了,你需要實現一個graphql到sql的介面,因為你的底層資料庫還用的是MySQL,而不是neo4j


早期用戶來簡單說一下。GraphQL你可以把他當成一個面向前端BFF中間件,當然主要也是前端自己維護,需要自己對接數據來源,能夠替代大部分數據型介面,網路傳輸方面避免了overfetch之類的情況。

和mysql和nosql直接的差別嘛。

首先mysql屬於RDBMS,sql只是和下層對話的介面。nosql是寬泛概念吧,需要有各自的查詢語言。

GraphQL可以類比成SQL,但是面向客戶端的只有類似SQL的DML,而DDL部分僅僅只有create。要改變schema的話,雖然也能在運行時改變,但是需要自行hack,官方沒有指明,當然也有現成的服務,如graphcool。

而TCL和DCL部分,GraphQL是不具備的。

估計是跟本身定位有關。

如果疏漏或錯誤,還望指正。


說道GraphQL,其實想順便問一下,一個公司在什麼樣的情況下,需要使用GraphQL?GraphQL能提高多少效率?能杜絕前後端關於介面欄位的限制嗎?


推薦閱讀:

Node.js+Node-webkit的開發模式前景如何?
你寫過的最好的 Node.js 腳本是什麼?
nodejs的回調函數里為什麼需要return?
請問一下,跨平台解決方案中,Qt 和 Electron 孰優孰劣?
webpack這個js模塊管理器(module bundler)怎麼樣?

TAG:前端開發 | API | Nodejs | REST | GraphQL |