GraphQL


一、GraphQL簡介

1、什么是GraphQL?

  GraphQL官網:https://graphql.org/,這個是英文的,https://graphql.js.cool/這個是中文的。

  GraphQL是一種用於API的查詢語言。GraphQL 既是一種用於 API 的查詢語言也是一個滿足你數據查詢的運行時。 GraphQL 對你的 API 中的數據提供了一套易於理解的完整描述,使得客戶端能夠准確地獲得它需要的數據,而且沒有任何冗余,也讓 API 更容易地隨着時間推移而演進,還能用於構建強大的開發者工具。

  GraphQL與數據庫、存儲技術和開發語言、框架無關。GraphQL的服務也不限定使用的傳輸技術,但是通長是使用HTTP(S)來傳輸。

  嵌套查詢,查詢是可以嵌套的,一次請求,獲得多個類型的數據,無需繼續鑽取數據,客戶端不會收到不需要的數據屬性。

  每當對GraphQL服務器進行查詢的時候,都會使用類型系統進行驗證。

  在Schema里定義類型:

  GraphQL通長被稱作是“聲明式數據獲取語言”。

  GraphQL的設計原則:

    層次結構性、以產品為中心、強類型、客戶端定制查詢、內省(Introspective)

2、GraphQL的歷史

  源自Facebook,2012年Facebook開始開發,2015年開源

3、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來現實時,我們通常可以通過訪問多次請求來收集數據。比如在這個示例中,我們可以通過下面的三步來實現:

1、 通過 /user/<id>獲取初始用戶數據

2、 通過/user/<id>/posts 返回用戶的所有帖子

3、 請求/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/

二、圖論(GraphQL Theory)

  圖論就是研究圖的,圖開源用來表示一組關聯的對象。可以把圖看作是一個包含數據點和連接的對象。例如:人機關系圖、家譜、公交線路圖

 

 

  這是一個無序圖,一個圖包含:

  1、頂點Vertices

  2、邊Edge

  3、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的結構、二叉樹

 

 

 

 三、Query(查詢)&Mutation(修改)

  這里是Git上面的一個API,可以進行簡單的使用https://developer.github.com/v4/explorer/,需要先登錄才可以。

1、GraphQL VS SQL

  SQL查詢數據庫;GraphQL查詢API

  SQL的數據存在數據表里;GraphQL的數據可以存放在任何地方

  SQL使用SELECT查詢數據;GraphQL使用Query

  SQL使用INSERT、UPDATE、DELETE來修改數據;GraphQL使用Mutation修改數據

  GraphQL還可以進行訂閱(通過socket)

2、查詢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

 

 2、修改Mutation

  Mutation也是根對象類型,Mutation和Query很像,有名字、可以有返回的選擇集,不同之處就是Mutation會修改后台數據的狀態。

 

 GraphQL查詢變量:

  代替寫死的參數值,可以動態賦值,使用$開頭。

3、訂閱Subscription

  Subscription允許我們監聽GraphQL API的實時數據變化,Subscription也是根類型,通過WebSocket,與Query和Mutation不同,Subscription保持鏈接打開狀態,如果想停止監聽,需要取消訂閱。

 

 4、內省Introspection

  一個非常強大的特性,Introspection可以讓你查詢當前API的schema,查詢可用類型:_schema,查詢類型明細:_type

 

 5、抽象語法樹Abstract Syntax Trees

  抽象語法樹AST,查詢文檔是字符串,查詢時被解析成AST,並在每個操作運行前進行嚴重,AST是要給層次結構的對象,代表了查詢,每一個操作都會被解析成AST(很重要)

四、Schema和Types

1、Schema是什么

  GraphQL會改變你進行設計的過程,使用REST的時候,可以把你的API看作是一組REST端點,而在GraphQL里你把你的API看作成是一組類型,為你暴露的API定義的這組數據類型就叫做Schema。

  設計Schema:

    Schema First:使前后端團隊在數據類型上保持一致

    GraphQL使用SDL(Schema Definition Language)語言來定義Schema,無論使用什么開發語言或者框架GraphQL的SDL都是一樣的,GraphQL的Schema就是定義了可用類型的文本文檔,它被客戶端和服務器端來驗證GraphQL請求。

2、定義Types

  GraphQL Schema的核心就是類型(Type),一個類型代表着一個自定義的對象,而這些對象則代表 了你的核心特征,類型有字段(Field),它代表了關聯每個對象的數據,每個字段都會返回一個特定的數據類型。Schema就是類型定義的集合,Schema定義文件的后綴名通常是.graphql

  類型定義:

    例子:嘆號表示不能為null

 

   Scalar Type標量類型:

    內置Int、Float、String、Boolean、ID

    可以自定義Scalar Type,Scalar Type不是對象類型,它沒有字段,例如:

 

   Enum枚舉類型:

    枚舉類型也是標量類型,它可以返回一組字符串中的一個值,例如:

 

 3、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

 

 4、Arguments參數

  GraphQL里的任何字段都可以由Arguments,Arguments必須有類型,這個類型應該是hischema中已經定義好的標量類型或者對象類型

 

   過濾數據:

    Arguments吧一定非得是費控的,使用可控字段可以添加可選參數(optional arguments/optional parameters)

 

   翻頁;

    要實現翻頁功能至少需要兩個可選參數(optional arguments),首先需要設定當前頁一次性返回的條目數(first、pageSize.....),然后還要設定從哪個位置開始獲取這些數據(start,pageIndex......)

 

   排序:

    方法有很多,可以使用enum來決定哪個字段可以用來排序

 

 5、Mutation修改

  Mutation也在schema里面定義,技術上Mutation和Query沒有區別,只是他們的意圖不同,Mutation是用來修改狀態的,Mutation的名稱里應該包含動詞。

 

 6、Input Types輸入類型

  Query和Mutation的參數可能會很多,這時最好使用Input Type來整理單數(arguments),Input Type和GraphQL里的對象類型很像,但是它只能用作輸入參數,Input Type可以用作於任何子墩

 

 7、Return Types返回類型

  Schema里所有的字段都可以返回定義好的主類型,但有時候需要返回一些關於查詢和修改的元信息,這時就可以創建一個返回類型。

 

 8、Subscription訂閱

  Subscription類型和GraphQL的SDL里的其他類型也沒有什么區別,在自定義對象類型的子墩上定義可用的Subscriptions。Subscription可用有參數

 

 9、Schema文檔

  編寫Schema的時候,可以為每個字段添加一些描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM