GraphQL on Rails(三) 結(jié)合Rails的修改API

GraphQL on Rails(一) GraphQL介紹
GraphQL on Rails(二) 結(jié)合Rails的查詢API

接著上一個(gè)寫(xiě)到的GraphQL在RailsAPI應(yīng)用中的查詢功能褪那,這次我們來(lái)實(shí)現(xiàn)修改數(shù)據(jù)的功能痢缎,修改數(shù)據(jù)的操作在GraphQL中被稱為 突變(mutation即修改數(shù)據(jù)),它在GraphQL schema中的定義是這樣的钢颂。

QuerySchema =  GraphQL::Schema.new(mutation: TODO)

我們還是延續(xù)上一篇的例子,一個(gè)博客系統(tǒng)白嘁,其中包含三個(gè)模型:Article心墅、UserComment持灰。

突變

mutation在GraphQL中與其他元素一樣也是一個(gè)類(lèi)型的定義盔夜,那么既然是類(lèi)型的定義,我們就可以將它存放在 types目錄下面堤魁,:

MutationType = GraphQL::ObjectType.define do
  # TODO
end

然后就像上面提到的那樣喂链,我們需要在schema定義中指定需要加載的mutation

QuerySchema =  GraphQL::Schema.new(query: QueryType, mutation: MutationType)

接下來(lái)我們就編寫(xiě) MutationType中的內(nèi)容,定義一下具體可以操作的數(shù)據(jù)類(lèi)型妥泉。既然構(gòu)建的是博客系統(tǒng)那么系統(tǒng)是要提供椭微,對(duì)文章的發(fā)布和修改,以及對(duì)文章記性評(píng)論涛漂,和違禁評(píng)論的刪除功能赏表。

MutationType = GraphQL::ObjectType.define do

  field :CreateArticle, field: ArticleMutations::Create
  
  field :UpdateArticle, field: ArticleMutations::Update 
  
  field :CreateComment, field: CommentMutations::Create

  field :DestroyComment, field: CommentMutations::Destroy

end

現(xiàn)在MutationType中就已經(jīng)有了這四種操作的類(lèi)型,可以看到上面的每一行定義中存在兩個(gè)field關(guān)鍵字匈仗,這其中第一個(gè)field是我們定義的MutationType的字段名瓢剿,后面的Symbol field才是正在的類(lèi)型定義存在的地方,當(dāng)然如果你愿意的話其實(shí)可以將它們直接寫(xiě)在 MutationType的定義當(dāng)中的悠轩,但是因?yàn)槌绦驈?fù)雜起來(lái)后间狂,像上面的這種寫(xiě)法更容易模塊化,所以使用這種寫(xiě)法火架。
我們將上面提到的四個(gè)mutations的文件存放在對(duì)應(yīng)的./app/graph/mutations 中

├── app
│   ├── graph
│   │   ├── fields
│   │   ├── schemas
|   |   ├── mutations
│   │   └── types

**app/graph/mutations/article_mutations.rb **

module ArticleMutations

  Create = GraphQL::Field.define do
    type -> { ArticleType }
    description 'create a article'

    argument :title, !types.String

    argument :content, !types.String

    resolve -> (obj, input_fields, ctx)  do
      ctx[:current_user].articles.create(title: input_fields['title'], content: input_fields['content'])
    end

  end

  Update = GraphQL::Field.define do
    type -> { ArticleType }
    description 'update title of article'

    argument :id, types.ID

    argument :title, !types.String

    resolve -> (obj, input_fields, ctx)  do
      article = Article.find_by(id: input_fields['id'])
      article.update(title: input_fields['title'])
      article
    end
  end
end

**app/graph/mutations/comment_mutations.rb **

module CommentMutations
  Create = GraphQL::Field.define do
    type -> { CommentType }
    description 'create a comment of article'

    argument :article_id, types.ID

    argument :content, !types.String

    resolve -> (obj, input_fields, ctx)  do
      article = Article.find_by(id: input_fields['article_id'])
      article.comments.create(content: input_fields['content'], user: ctx[:current_user])
    end

  end

  Destroy = GraphQL::Field.define do
    type -> { types.Boolean }
    description 'delete a comment'

    argument :id, types.ID

    resolve -> (obj, input_fields, ctx)  do
      !!Comment.delete(input_fields['id'])
    end
  end
end

從上面的兩段代碼看到鉴象,mutation其實(shí)和query是基本一樣的類(lèi)型定義忙菠,首先由type指定修改數(shù)據(jù)后的返回值類(lèi)型,argument定義可以傳遞的參數(shù)纺弊,resolve 方法的block參數(shù)是最后具體執(zhí)行操作的代碼牛欢。其中還有一個(gè)需要注意的就是 resolve 方法中的第三個(gè)參數(shù),ctx (context) 它是用于存放controller中傳遞進(jìn)來(lái)的上下文數(shù)據(jù)淆游,我們這個(gè)博客系統(tǒng)的創(chuàng)建數(shù)據(jù)操作都需要用戶信息所以傍睹,需要在controller中把當(dāng)前用戶傳進(jìn)來(lái)。

class QueriesController < ApplicationController
  def create
    result = ::QuerySchema.execute(params[:query], context: {current_user: current_user})
    render json: result
  end
end  

接下來(lái)犹菱,讓我們來(lái)創(chuàng)建一個(gè)文章看看效果:


Paste_Image.png

文章被創(chuàng)建成功拾稳,并且返回了作者的ID以及,文章的ID和標(biāo)題腊脱。

總結(jié)

通過(guò)上面的實(shí)例访得,我們可以看出GraphQL中不管是查詢還是突變都保持著統(tǒng)一的類(lèi)型系統(tǒng)的樣子,其中有要注意的幾點(diǎn)是:突變字段中的 resolve方法的返回值的類(lèi)型要和聲明的類(lèi)型一致陕凹,還有就是多個(gè)突變操作在一個(gè)查詢中是順序執(zhí)行的悍抑。
后面的話這一系列文章會(huì)寫(xiě)到GraphQL的其他高級(jí)功能在Rails中的應(yīng)用,以及GraphQL查詢的優(yōu)化方案等杜耙。

最后編輯于
?著作權(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)容