GraphQL on Rails(一) GraphQL介紹

GraphQL

GraphQL按照官方的說(shuō)法它是一門(mén)聲明式的查詢語(yǔ)言段只,實(shí)際上它是領(lǐng)域特定查詢語(yǔ) DSQL趣惠,它通過(guò)定義的schema系統(tǒng)將復(fù)雜的邏輯拆分成細(xì)粒度的數(shù)據(jù)結(jié)構(gòu)狸棍,來(lái)讓前端應(yīng)用的開(kāi)發(fā)者能夠通過(guò)GraphQL提供的類型查詢系統(tǒng),自由定制請(qǐng)求數(shù)據(jù)的能力味悄。

GraphQL與RESTful

目前大多數(shù)應(yīng)用的API采用的都是流行的RESTful API草戈,但是對(duì)于很多需求變更頻繁的,數(shù)據(jù)查詢顆粒的小的應(yīng)用來(lái)說(shuō)侍瑟,使用RESTful的API總是在不斷的迭代唐片,不斷的更新版本丙猬。這會(huì)導(dǎo)致應(yīng)用的API系統(tǒng)過(guò)于復(fù)雜,而且通常最后又大量冗余的API進(jìn)而變動(dòng)難以維護(hù)费韭。

“The REST interface is designed to be efficient for large-grain hypermedia data transfer…” - Dr Roy T Fielding, Author of REST

其實(shí)REST本身更適合數(shù)據(jù)力度大茧球,需求變更不頻繁的應(yīng)用場(chǎng)景,而在細(xì)粒度的應(yīng)用場(chǎng)景下的解決方案揽思,在Facebook的復(fù)雜系統(tǒng)中應(yīng)運(yùn)而生袜腥,GraphQL被用于解決細(xì)粒度的API問(wèn)題已經(jīng)3年多了,處理了260多億次的請(qǐng)求钉汗,這注意證明它在真實(shí)的場(chǎng)景下是經(jīng)得起考驗(yàn)的羹令。

整個(gè)GraphQL的核心就是一個(gè)類型定義系統(tǒng),通過(guò)定義各種可能的查詢類型和所有的返回?cái)?shù)據(jù)的類型损痰,來(lái)構(gòu)建一個(gè)查詢系統(tǒng)福侈,讓客戶端通過(guò)統(tǒng)一的查詢語(yǔ)言,來(lái)對(duì)系統(tǒng)中的類型進(jìn)行匹配卢未,并最終返回肪凛,相匹配的數(shù)據(jù)。

GraphQL 由以下組件構(gòu)成:

  • 類型系統(tǒng)(Type System)
  • 查詢語(yǔ)言(Query Language)
  • 執(zhí)行語(yǔ)義(Execution Semantics)
  • 靜態(tài)驗(yàn)證(Static Validation)
  • 類型檢查(Type Introspection)

類型

GraphQL中類型系統(tǒng)是最重要的組成部分之一辽社,其中提供的類型分為兩種伟墙,一種是標(biāo)量類型,用于表示最細(xì)粒度的類型滴铅,這些類型基本可以和JavaScript戳葵,Ruby及其他通用編程語(yǔ)言對(duì)應(yīng)上。
標(biāo)量類型:

  • Int : 整數(shù)汉匙,對(duì)應(yīng) JavaScript 的Number
  • Float :浮點(diǎn)數(shù)拱烁,對(duì)應(yīng) JavaScript 的 Number
  • Boolean:布爾值,對(duì)應(yīng) JavaScript 的 Boolean
  • String : 字符串噩翠,對(duì)應(yīng) JavaScript 的 String
  • ID : D 值戏自,是一個(gè)序列化后值唯一的字符串,可以視作對(duì)應(yīng) ES 2015 新增的 Symbol

其他的高級(jí)類型:

  • Object : 對(duì)象類型 伤锚,用于表示GraphQL返回類型樹(shù)的中間層級(jí)擅笔,標(biāo)量類型表示的都是葉子節(jié)點(diǎn),在GraphQL基本上所以的類型都是Object類型屯援,它包含有一個(gè)name字段來(lái)描述定義的類型和fields字段描述該類型的完整數(shù)據(jù)結(jié)構(gòu)猛们。
var AddressType = new GraphQLObjectType({
    name: 'Address',
    fields: {
      street: { type: GraphQLString },
      number: { type: GraphQLInt },
      formatted: {
        type: GraphQLString,
        resolve(obj) {
          return obj.number + ' ' + obj.street
        }
      }
    }
});
  • Interface : 接口類型 用于描述多個(gè)類型中通用的字段
var EntityType = new GraphQLInterfaceType({
    name: 'Entity',
    fields: {
      name: { type: GraphQLString }
    }
});
  • Union : 聯(lián)合 它有點(diǎn)像可選類型,用于表示這一個(gè)字段可能是一個(gè)類型集合下的某一種類型玄呛。
var PetType = new GraphQLUnionType({
    name: 'Pet',
    types: [DogType, CatType],
    resolveType(value) {
      if (value instanceof Dog) {
        return DogType;
      }
      if (value instanceof Cat) {
        return CatType;
      }
    }
});
  • Enum :枚舉類型
var RGBType = new GraphQLEnumType({
    name: 'RGB',
    values: { 
      RED: { value: 0 },
      GREEN: { value: 1 },
      BLUE: { value: 2 } 
    }
});
  • List : 列表類型
var PersonType = new GraphQLObjectType({
   name: 'Person',
    fields: () => ({
      parents: { type: new GraphQLList(Person) },
      children: { type: new GraphQLList(Person) },
    })
});
  • Non-Null : 不為空類型阅懦,用于表示返回的字段不為空,如果為空就會(huì)發(fā)生異常徘铝,可用于數(shù)據(jù)庫(kù)的主鍵耳胎。
var RowType = new GraphQLObjectType({
    name: 'Row',
    fields: () => ({
      id: { type: new GraphQLNonNull(GraphQLString) }
    })
});

查詢

GraphQL的客戶端惯吕,是通過(guò)一個(gè)查詢字符串通過(guò),GraphQL服務(wù)可以解析驗(yàn)證并執(zhí)行這樣的查詢請(qǐng)求字符串怕午,一個(gè)查詢字符串有兩部分組成:操作(Operation)和片段(Fragments) 一個(gè) query 可以包含多個(gè)操作和片段废登。只有包含操作的 query 才會(huì)被 GraphQL 服務(wù)執(zhí)行。但是不包含操作郁惜,只有片段的 query 也會(huì)被 GraphQL 服務(wù)解析驗(yàn)證堡距,這樣一份片段就可以在多個(gè) query 文檔內(nèi)使用。

GraphQL 規(guī)范支持兩種操作:

let schema = new GraphQLSchema({ query: UserType mutation: UpdateAgeType});
  • query:僅獲取數(shù)據(jù)(fetch)的只讀請(qǐng)求
query {
    user(id: 3500401) {
      id,
      name,
      age
    }
}
  • mutation:獲取數(shù)據(jù)后還有寫(xiě)操作的請(qǐng)求
mutation {
    updateAage
}

其中GraphQL對(duì)數(shù)據(jù)的修改稱為mutation 兆蕉,它在GraphQL的查詢系統(tǒng)中是按照順序序列化執(zhí)行的羽戒。

查詢請(qǐng)求模型:


總結(jié)

GraphQL在技術(shù)上提供了區(qū)別于REST的解決方案,很好的解決了數(shù)據(jù)細(xì)粒度頻繁變更的問(wèn)題虎韵,使得數(shù)據(jù)和接口得到了解綁易稠,在生態(tài)圈方便面,現(xiàn)已經(jīng)有很多語(yǔ)言的GraphQL實(shí)現(xiàn)(Python 包蓝、Ruby 等)可以參見(jiàn) GraphQL Awesome list驶社。在應(yīng)用方面雖然是2015年才被Facebook公布并且開(kāi)源的,但是它已經(jīng)在Facebook的應(yīng)用系統(tǒng)中工作了快四年之久测萎。而且現(xiàn)在不少國(guó)內(nèi)的團(tuán)隊(duì)(比如淘寶)也已經(jīng)在使用GraphQL構(gòu)建應(yīng)用系統(tǒng)的API亡电,這些都足以證明這項(xiàng)技術(shù)的市場(chǎng)和潛力了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末硅瞧,一起剝皮案震驚了整個(gè)濱河市份乒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌零酪,老刑警劉巖冒嫡,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拇勃,死亡現(xiàn)場(chǎng)離奇詭異四苇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)方咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)月腋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瓣赂,你說(shuō)我怎么就攤上這事榆骚。” “怎么了煌集?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵妓肢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我苫纤,道長(zhǎng)碉钠,這世上最難降的妖魔是什么纲缓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮喊废,結(jié)果婚禮上祝高,老公的妹妹穿的比我還像新娘。我一直安慰自己污筷,他們只是感情好工闺,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瓣蛀,像睡著了一般陆蟆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惋增,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天遍搞,我揣著相機(jī)與錄音,去河邊找鬼器腋。 笑死溪猿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纫塌。 我是一名探鬼主播诊县,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼措左!你這毒婦竟也來(lái)了依痊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怎披,失蹤者是張志新(化名)和其女友劉穎胸嘁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體凉逛,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡性宏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了状飞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毫胜。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖诬辈,靈堂內(nèi)的尸體忽然破棺而出酵使,到底是詐尸還是另有隱情,我是刑警寧澤焙糟,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布口渔,位于F島的核電站,受9級(jí)特大地震影響穿撮,放射性物質(zhì)發(fā)生泄漏缺脉。R本人自食惡果不足惜瞧哟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枪向。 院中可真熱鬧勤揩,春花似錦、人聲如沸秘蛔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)深员。三九已至负蠕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間倦畅,已是汗流浹背遮糖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叠赐,地道東北人欲账。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像芭概,于是被迫代替她去往敵國(guó)和親赛不。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理罢洲,服務(wù)發(fā)現(xiàn)踢故,斷路器,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法惹苗,類相關(guān)的語(yǔ)法殿较,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法桩蓉,異常的語(yǔ)法淋纲,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,581評(píng)論 18 399
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    Joyyx閱讀 8,320評(píng)論 0 16
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    草里有只羊閱讀 18,291評(píng)論 0 85
  • 記憶力不好的人,總愛(ài)做夢(mèng)触机。 而我好像就是這么一個(gè)人帚戳。 曾經(jīng)記憶很好的時(shí)候玷或,睡覺(jué)睡的很熟儡首,大概是白天里用腦強(qiáng)度比較大...
    熏爐閱讀 291評(píng)論 0 0