如何使用GraphQL描馅,Koa和MongoDB設置功能強大的API(三)

歡迎來到我們的第三部分系列把夸,我們在其中設置了一個強大的API 到目前為止,我們已經實現(xiàn)了基本的CRUD功能铭污。

隨著我們的應用程序的增長恋日,我們的Mutation數(shù)也在增 為了擁有盡可能干凈的代碼庫膀篮,我們應該將mutations提取到專用文件中。這樣我們就可以確保我們的代碼是模塊化的岂膳,并分成可維護的塊各拷。

讓我們創(chuàng)建一個文件夾graphql/mutations和文件夾中創(chuàng)建addGadget.js,updateGadget和removeGadget文件..

我們只是將Mutation對象放入文件并導出它們闷营。

將addGadgetMutation移動到單獨的文件
graphql/mutations/addGadget.js

const { GraphQLObjectType, GraphQLString } = require('graphql');
const gadgetGraphQLType =  require('./../gadgetType');
const Gadget = require('./../../models/gadget');

module.exports = {
  type: gadgetGraphQLType,
  args: {
    name: { type: GraphQLString },
    release_date: { type: GraphQLString },
    by_company: { type: GraphQLString },
    price: { type: GraphQLString }
  },
  resolve(parent, args) {
    const newGadget = new Gadget({
      name: args.name,
      release_date: args.release_date,
      by_company: args.by_company,
      price: args.price,
    })

    return newGadget.save();
  }
};

更新mutations;
graphql/mutations/updateGadget.js

const { GraphQLObjectType, GraphQLString } = require('graphql');
const gadgetGraphQLType =  require('./../gadgetType');
const Gadget = require('./../../models/gadget');

module.exports = {
  type: gadgetGraphQLType,
  args: {
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    release_date: { type: GraphQLString },
    by_company: { type: GraphQLString },
    price: { type: GraphQLString }
  },
  resolve(parent, args) {
    return Gadget.findById(args.id)
      .then(gadget => {
        gadget.name = args.name,
        gadget.release_date = args.release_date,
        gadget.by_company = args.by_company,
        gadget.price = args.price

        return gadget.save()

      })
      .then(updatedGadget => updatedGadget)
      .catch(err => console.log(err))
  }
};

最后是刪除mutations烤黍。
graphql/mutations/removeGadget.js

const { GraphQLObjectType, GraphQLString } = require('graphql');
const gadgetGraphQLType =  require('./../gadgetType');
const Gadget = require('./../../models/gadget');

module.exports = {
  type: gadgetGraphQLType,
  args: {
    id: { type: GraphQLString }
  },
  resolve(parent, args) {
    return Gadget.findOneAndDelete(args.id).exec()
      .then(gadget => gadget.remove())
      .then(deletedGadget => deletedGadget)
      .catch(err => console.log(err))
  }
};

我們將它們放在單獨的文件中后,我們就可以更改graphql/mutations.js文件了傻盟。

const { GraphQLObjectType, GraphQLString } = require('graphql');

const addGadget = require('./mutations/addGadget');
const updateGadget = require('./mutations/updateGadget');
const removeGadget = require('./mutations/removeGadget');

const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    addGadget,
    updateGadget,
    removeGadget,
  }
})

module.exports = Mutation;

非常簡潔

這就是我們的項目現(xiàn)在的樣子;

15573832643778.jpg

我們的GraphQL API正在形成良好的狀態(tài)速蕊。到目前為止,我們有一個專門的mutations文件夾娘赴。讓我們對查詢做同樣的事情规哲。

為查詢創(chuàng)建一個文件夾 - graphql/queries并將rootQuery.js文件放在那里。

在rootQuery.js文件內部诽表,我們放置了只獲取數(shù)據(jù)的所有查詢唉锌。這樣我們就有了用于查詢和mutations的單獨文件夾。查詢和mutations之間的區(qū)別很簡單 - 查詢只是從數(shù)據(jù)庫中讀取數(shù)據(jù)竿奏,mutations會改變我們數(shù)據(jù)庫的狀態(tài)袄简。

graphql/queries/rootQuery.js

const { GraphQLObjectType, GraphQLString, GraphQLList } =  require('graphql');

const gadgetGraphQLType =  require('./../gadgetType');
const Gadget = require('../../models/gadget');
const queryAllGadgets = require('./queryAllGadgets')

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    gadget: {
      type: gadgetGraphQLType,
      args: { id: { type: GraphQLString }},
      resolve(parent, args) {
        return Gadget.findById(args.id)
      }
    },

  }
})

module.exports = RootQuery;

將rootQuery導入到我們的 schema.js

const { GraphQLSchema } = require('graphql');

const RootQuery = require('./queries/rootQuery');
const Mutations = require('./mutations');


module.exports = new GraphQLSchema({
  query: RootQuery,
  mutation: Mutations
});

現(xiàn)在在rootQuery中我們指定所有查詢。創(chuàng)建一個文件泛啸,用于獲取所有數(shù)據(jù)并按ID獲取數(shù)據(jù)绿语。

  • graphql/queries/queryAllGadgets.js
  • graphql/queries/queryGadgetById.js
    將以下邏輯放在里面 graphql/queries/queryGadgetById.js
const { GraphQLString } =  require('graphql');
const gadgetGraphQLType = require('./../gadgetType');
const Gadget = require('../../models/gadget');

module.exports = {
  type: gadgetGraphQLType,
  args: { id: { type: GraphQLString }},
  resolve(parent, args) {
    return Gadget.findById(args.id)
  }
},

并獲取所有數(shù)據(jù) - graphql/queries/queryAllGadgets.js

const { GraphQLList } =  require('graphql');
const gadgetGraphQLType = require('./../gadgetType');
const Gadget = require('../../models/gadget');

module.exports = {
  type: new GraphQLList(gadgetGraphQLType),
  args: {},
  resolve() {
    return Gadget.find({})
  }
}

請注意新類型GraphQLList- 如果我們想要返回對象列表(在這種情況下為所有數(shù)據(jù)),則使用此類型候址。

現(xiàn)在我們必須將查詢導入到我們的 rootQuery

const { GraphQLObjectType } =  require('graphql');

const Gadget = require('../../models/gadget');
const queryAllGadgets = require('./queryAllGadgets')
const queryGadgetById = require('./queryGadgetById');

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    queryGadgetById,
    queryAllGadgets,
  }
})

module.exports = RootQuery;

瞧吕粹!現(xiàn)在,讓我們從數(shù)據(jù)庫中查詢所有數(shù)據(jù)岗仑。

15573833506873.jpg

這是GraphQL查詢;

{
  queryAllGadgets {
    name,
    id,
    price,
    release_date,
    by_company
  }
}

我們的項目結構應如下所示;

15573833657744.jpg

不要忘記更新我們使用的路徑gadgetType(mutations和查詢)

const gadgetGraphQLType = require('./../types/gadgetType');

測試我們的查詢

在轉向更高級的概念之前匹耕,我想向您展示一個工具,讓我們可以查詢graphql查詢荠雕,如果您曾經使用過postman或Insomnia稳其,您會感到賓至如歸。

我使用Insomnia舞虱,因為它是免費的欢际,具有開箱即用的強大功能母市,并且是開源的矾兜。

免責聲明:我與Insomnia無關 - 我只是喜歡這個工具。

15573834500207.jpg

打開該工具患久,創(chuàng)建一個名為的新請求queryAllGadgets椅寺。在頂部我們的localhost地址(http:// localhost:9000 / graphql)并指定正文是graphQL浑槽。


15573835071141.jpg

最后,將graphQL查詢放在body請求中返帕。

15573835129605.jpg

我們現(xiàn)在可以隨意地查詢graphQL桐玻,就像我們使用REST一樣。如果REST可以做到這一點荆萤,GraphQL也可以镊靴。

其他章節(jié)

如何使用GraphQL,Koa和MongoDB設置功能強大的API(一)
如何使用GraphQL链韭,Koa和MongoDB設置功能強大的API(二)
如何使用GraphQL偏竟,Koa和MongoDB設置功能強大的API(三)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市敞峭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旋讹,老刑警劉巖殖蚕,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異沉迹,居然都是意外死亡睦疫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門鞭呕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笼痛,“玉大人,你說我怎么就攤上這事琅拌∮б粒” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵进宝,是天一觀的道長刻坊。 經常有香客問我,道長党晋,這世上最難降的妖魔是什么谭胚? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮未玻,結果婚禮上灾而,老公的妹妹穿的比我還像新娘。我一直安慰自己扳剿,他們只是感情好旁趟,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著庇绽,像睡著了一般锡搜。 火紅的嫁衣襯著肌膚如雪橙困。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天耕餐,我揣著相機與錄音凡傅,去河邊找鬼。 笑死肠缔,一個胖子當著我的面吹牛夏跷,可吹牛的內容都是我干的。 我是一名探鬼主播明未,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拓春,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亚隅?” 一聲冷哼從身側響起硼莽,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煮纵,沒想到半個月后懂鸵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡行疏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年匆光,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酿联。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡终息,死狀恐怖,靈堂內的尸體忽然破棺而出贞让,到底是詐尸還是另有隱情周崭,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布喳张,位于F島的核電站续镇,受9級特大地震影響,放射性物質發(fā)生泄漏销部。R本人自食惡果不足惜摸航,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舅桩。 院中可真熱鬧酱虎,春花似錦、人聲如沸擂涛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爹土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間踩身,已是汗流浹背胀茵。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挟阻,地道東北人琼娘。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像附鸽,于是被迫代替她去往敵國和親脱拼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354