1、GraphQL簡介html
一、什麼是GraphQL?git
GraphQL官網:https://graphql.org/,這個是英文的,https://graphql.js.cool/這個是中文的。github
GraphQL是一種用於API的查詢語言。GraphQL 既是一種用於 API 的查詢語言也是一個知足你數據查詢的運行時。 GraphQL 對你的 API 中的數據提供了一套易於理解的完整描述,使得客戶端可以準確地得到它須要的數據,並且沒有任何冗餘,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。web
GraphQL與數據庫、存儲技術和開發語言、框架無關。GraphQL的服務也不限定使用的傳輸技術,可是通長是使用HTTP(S)來傳輸。數據庫
嵌套查詢,查詢是能夠嵌套的,一次請求,得到多個類型的數據,無需繼續鑽取數據,客戶端不會收到不須要的數據屬性。後端
每當對GraphQL服務器進行查詢的時候,都會使用類型系統進行驗證。api
在Schema裏定義類型:服務器
GraphQL通長被稱做是「聲明式數據獲取語言」。數據結構
GraphQL的設計原則:app
層次結構性、以產品爲中心、強類型、客戶端定製查詢、內省(Introspective)
二、GraphQL的歷史
源自Facebook,2012年Facebook開始開發,2015年開源
三、GraphQL和REST
至於REST的一些概念,開源參考一下以前的一篇隨筆,點擊這裏
前面提到GraphQL能夠理解爲基於RESTful的一種封裝,目的在於構建使Client更加易用的服務,能夠說GraphQL是更好的RESTful設計。在過去的十多年中,REST已經成爲設計web api的標準(雖然只是一個模糊的標準)。它提供了一些很棒的想法,好比無狀態服務器和結構化的資源訪問。然而REST api表現得過於僵化,沒法跟上訪問它們的客戶的快速變化的需求。 GraphQL的開發是爲了應付更多的靈活性和效率,它解決了與REST api交互時開發人員所經歷的許多缺點和低效之處。 爲了說明在從API獲取數據時REST和GraphQL之間的主要區別,讓咱們考慮一個簡單的示例場景:在blog應用程序中,應用程序須要顯示特定用戶的文章的標題。同一屏幕還顯示該用戶最後3個關注者的名稱。REST和GraphQL如何解決這種狀況?
使用REST API來現實時,咱們一般能夠經過訪問屢次請求來收集數據。好比在這個示例中,咱們能夠經過下面的三步來實現:
一、 經過 /user/<id>獲取初始用戶數據
二、 經過/user/<id>/posts 返回用戶的全部帖子
三、 請求/user/<id>/followers,返回每一個用戶的關注者列表
調用關係以下圖所示:
若是用GraphQL的話,咱們只須要一次請求就能夠完成上述的需求:
在GraphQL的世界裏咱們不用多取數據,也不用擔憂數據取少了,咱們只須要按需獲取便可。
REST最多見的問題之一是API的返回數據過多或者過少,這是由於客戶端下載數據的惟一方法是經過訪問返回固定數據結構的endpoint,這就會致使咱們設計API很是困難,由於它既要可以爲客戶提供精確的數據需求,又須要知足不一樣調用者的需求,這自己就是相互矛盾的。GraphQL的發明者Lee Byron提出了一個很重要的概念: 「用圖形來思考,而不是endpoint」。
可使用GraphQL管理REST端點
GitHub的API有四個版本,第三個版本使用REST,第四個就是用的GraphQL。https://developer.github.com/v4/explorer/
2、圖論(GraphQL Theory)
圖論就是研究圖的,圖開源用來表示一組關聯的對象。能夠把圖看做是一個包含數據點和鏈接的對象。例如:人機關係圖、家譜、公交線路圖
這是一個無序圖,一個圖包含:
一、頂點Vertices
二、邊Edge
三、G=(V,E)
G:圖
V:頂點
E:邊
上圖中:
Vertices={1,2,3,4}
Edge={{1,2},{1,3},{1,4,},{2,4},{3,4}}
有向圖:
有向圖的邊有箭頭
Vertices={1,2,3,4}
Edges=({1,2},{1,3},{3,4})
Graph=({1,2,3,4},{1,2},{1,3},{3,4})
當有向圖的序對改變了,圖就變了
圖就變成了Graph=({1,2,3,4},{4,3},{3,1},{1,2})
樹形圖也是圖,好比HTML的結構、二叉樹
3、Query(查詢)&Mutation(修改)
這裏是Git上面的一個API,能夠進行簡單的使用https://developer.github.com/v4/explorer/,須要先登陸才能夠。
一、GraphQL VS SQL
SQL查詢數據庫;GraphQL查詢API
SQL的數據存在數據表裏;GraphQL的數據能夠存放在任何地方
SQL使用SELECT查詢數據;GraphQL使用Query
SQL使用INSERT、UPDATE、DELETE來修改數據;GraphQL使用Mutation修改數據
GraphQL還能夠進行訂閱(經過socket)
二、查詢Query
GraphQL的請求,GraphQL查詢的內容經過HTTP POST的Body發送給GraphQL端點。
查詢就是從API獲取數據,它表示了你想從GraphQL服務器獲取的數據;經過字段(field)來請求查詢的數據;這些字段和查詢結果的JSON響應的字段對應。
GraphQL查詢錯誤:
成功查詢的JSON結果裏面包含一個data字段,不成功的查詢結果裏面包含一個errors字段,裏面有具體的錯誤信息。JSON相應結果可同時包data和errors字段。
errorTest這個地段是吧存在的,因此在後面會包含一個errors字段,裏面有具體的錯誤信息。
Query是GraphQL的一個類型,叫作根類型,由於它映射的事一個操做,而操做則表明着查詢文檔的根節點。
查詢可用的字段是在schema裏面定義的;可用查看文檔
使用ALT+Space,可用顯示參數
GraphQL修改和查詢很像,就是意圖不一樣。
GraphQL字段類型:
Scalar Type:Int、String、Float、Boolean、ID
Object Type
GraphQL片斷Fragments
Fragments就是可用服用的選擇集
片斷(Fragments):
假設咱們的app有比較複雜的頁面,講正反派主角及其友軍分爲兩撥。你立馬就能想到對應的查詢會變得複雜,由於咱們須要將一些字段重複至少一次——兩房各一次做比較。
這就是爲什麼GraphQL包含了稱做片斷的可複用單元,片斷使你可以阻止一組字段,而後在他們須要的地方引入,下面的例子展現瞭如何使用片斷解決上述場景:
GraphQL聯合類型Union Type
若是你想返回不止一種類型,那麼您可使用Union Type
GraphQL接口Interface
二、修改Mutation
Mutation也是根對象類型,Mutation和Query很像,有名字、能夠有返回的選擇集,不一樣之處就是Mutation會修改後臺數據的狀態。
GraphQL查詢變量:
代替寫死的參數值,能夠動態賦值,使用$開頭。
三、訂閱Subscription
Subscription容許咱們監聽GraphQL API的實時數據變化,Subscription也是根類型,經過WebSocket,與Query和Mutation不一樣,Subscription保持連接打開狀態,若是想中止監聽,須要取消訂閱。
四、內省Introspection
一個很是強大的特性,Introspection可讓你查詢當前API的schema,查詢可用類型:_schema,查詢類型明細:_type
五、抽象語法樹Abstract Syntax Trees
抽象語法樹AST,查詢文檔是字符串,查詢時被解析成AST,並在每一個操做運行前進行嚴重,AST是要給層次結構的對象,表明了查詢,每個操做都會被解析成AST(很重要)
4、Schema和Types
一、Schema是什麼
GraphQL會改變你進行設計的過程,使用REST的時候,能夠把你的API看做是一組REST端點,而在GraphQL裏你把你的API看做成是一組類型,爲你暴露的API定義的這組數據類型就叫作Schema。
設計Schema:
Schema First:使先後端團隊在數據類型上保持一致
GraphQL使用SDL(Schema Definition Language)語言來定義Schema,不管使用什麼開發語言或者框架GraphQL的SDL都是同樣的,GraphQL的Schema就是定義了可用類型的文本文檔,它被客戶端和服務器端來驗證GraphQL請求。
二、定義Types
GraphQL Schema的核心就是類型(Type),一個類型表明着一個自定義的對象,而這些對象則表明 了你的核心特徵,類型有字段(Field),它表明了關聯每一個對象的數據,每一個字段都會返回一個特定的數據類型。Schema就是類型定義的集合,Schema定義文件的後綴名一般是.graphql
類型定義:
例子:歎號表示不能爲null
Scalar Type標量類型:
內置Int、Float、String、Boolean、ID
能夠自定義Scalar Type,Scalar Type不是對象類型,它沒有字段,例如:
Enum枚舉類型:
枚舉類型也是標量類型,它能夠返回一組字符串中的一個值,例如:
三、Connections和List
建立Schema時,能夠定義返回一個由任意Graph類型組成的列表,例如:[String]、[User],列表頁能夠由不一樣的類型組成,使用Union Type或者Interface Type,[Int]、[Int!]、[Int]!、[Int!]!的區別
一對一鏈接
圖論裏,兩個對象之間的鏈接叫作邊(Edge),而由一個對象鏈接到另一個對象的鏈接就是一對一的鏈接
一對多鏈接
要儘可能報紙GraphQL服務的無向性,也就是說能夠從圖的任何一個定點開始遍歷;針對上例,添加一條從User類型回到Photo的路徑:
多對多鏈接
例如標籤操做Tagging
多對多鏈接,須要在雙方類型裏都添加List字段,一個多對多鏈接由兩個一對多鏈接組成
建立多對多鏈接時,由時須要保存關係自己,這時就須要經過類型(Through Type),把邊(Edge)定義爲一個自定義對象類型,至關於鏈接兩個節點的節點。由不一樣類型組成邊的列表,GraphQL裏的列表不必定非得是同一種理性,使用Union Type,Interface結合Fragment能夠達到此目的。
Union Type
Union Type,咱們能夠用它返回多種類型中的一種類型
Interface:
爲了保證某些類型必須包含特定的字段,咱們可使用接口Interface
四、Arguments參數
GraphQL裏的任何字段均可以由Arguments,Arguments必須有類型,這個類型應該是hischema中已經定義好的標量類型或者對象類型
過濾數據:
Arguments吧必定非得是費控的,使用可控字段能夠添加可選參數(optional arguments/optional parameters)
翻頁;
要實現翻頁功能至少須要兩個可選參數(optional arguments),首先須要設定當前頁一次性返回的條目數(first、pageSize.....),而後還要設定從哪一個位置開始獲取這些數據(start,pageIndex......)
排序:
方法有不少,可使用enum來決定哪一個字段能夠用來排序
五、Mutation修改
Mutation也在schema裏面定義,技術上Mutation和Query沒有區別,只是他們的意圖不一樣,Mutation是用來修改狀態的,Mutation的名稱裏應該包含動詞。
六、Input Types輸入類型
Query和Mutation的參數可能會不少,這時最好使用Input Type來整理單數(arguments),Input Type和GraphQL裏的對象類型很像,可是它只能用做輸入參數,Input Type能夠用做於任何子墩
七、Return Types返回類型
Schema裏全部的字段均可以返回定義好的主類型,但有時候須要返回一些關於查詢和修改的元信息,這時就能夠建立一個返回類型。
八、Subscription訂閱
Subscription類型和GraphQL的SDL裏的其餘類型也沒有什麼區別,在自定義對象類型的子墩上定義可用的Subscriptions。Subscription可用有參數
九、Schema文檔
編寫Schema的時候,能夠爲每一個字段添加一些描述