graphql

什么是GraphQL

GraphQL是比REST更高效、強(qiáng)大和靈活的新一代API標(biāo)準(zhǔn)。Facebook開(kāi)發(fā)了GraphQL并且將其開(kāi)源,目前其由一大群來(lái)自全球各地的公司和個(gè)人維護(hù)恕出。

注意到GraphQL是API標(biāo)準(zhǔn),不要看到QL結(jié)尾就以為其是一種數(shù)據(jù)庫(kù)技術(shù)浙巫。

比REST更靈活的一種選擇

REST是目前比較流行的一種暴露服務(wù)端數(shù)據(jù)的常見(jiàn)方式刷后,其簡(jiǎn)化了客戶(hù)端尤其是移動(dòng)端和服務(wù)器交互的流程。但是隨著業(yè)務(wù)變得復(fù)雜尝胆,有些情況變得棘手:

移動(dòng)端數(shù)量的增多,對(duì)數(shù)據(jù)的效率要求變高

移動(dòng)端和PC端相比护桦,是需要提高對(duì)數(shù)據(jù)獲取的效率的含衔,這個(gè)效率就是說(shuō)要減少網(wǎng)絡(luò)請(qǐng)求、要減少無(wú)用數(shù)據(jù)的傳輸二庵。

應(yīng)對(duì)復(fù)雜的前端框架和平臺(tái)

現(xiàn)在的情況是僅維護(hù)一套API來(lái)應(yīng)對(duì)不同框架和平臺(tái)的請(qǐng)求贪染。PC端一個(gè)頁(yè)面比移動(dòng)端一個(gè)頁(yè)面展示的內(nèi)容要多很多,之前后端提供給PC端的API如果直接提供給移動(dòng)端來(lái)使用勢(shì)必造成資源浪費(fèi)催享。所以移動(dòng)端的人會(huì)去找后端的人干一架杭隙,結(jié)果要么是后端再給移動(dòng)端單獨(dú)寫(xiě)一套API,要么就是移動(dòng)端忍受著API請(qǐng)求返回?cái)?shù)據(jù)中存在大量冗余的數(shù)據(jù)因妙。

需要更快速地迭代更新

互聯(lián)網(wǎng)時(shí)代最大的特色除了加班也許就是快了痰憎。好多公司在喊著小步快跑、快速試錯(cuò)攀涵,畢竟市場(chǎng)不等人信殊。然而REST標(biāo)準(zhǔn)的API似乎很難快速地跟上這快跑的節(jié)奏。也許一個(gè)API剛出來(lái)汁果,產(chǎn)品那邊已經(jīng)改了原型涡拘,界面重新設(shè)計(jì)了。這時(shí)候就要麻煩后端同學(xué)加個(gè)班把接口改一下吧据德。

誰(shuí)在用GraphQL

一個(gè)產(chǎn)品的流行鳄乏,肯定是解決了目前的某些痛點(diǎn)。雖然GraqhQL目前在國(guó)內(nèi)還不算流行棘利,可是在美利堅(jiān)已經(jīng)有不少巨頭在使用了:


image.png

GraphQL vs REST
我們來(lái)看一下對(duì)于不同API標(biāo)準(zhǔn)下橱野,從服務(wù)端獲取數(shù)據(jù)的區(qū)別。比如在REST API標(biāo)準(zhǔn)下善玫,有三個(gè)接口:

/users/

該接口返回某用戶(hù)基本信息

/users/posts

該接口返回某用戶(hù)所有的文章

/users/followers

該接口返回某用戶(hù)所有的關(guān)注者


image.png

如圖所示水援,要通過(guò)三個(gè)不同的請(qǐng)求才能獲得某用戶(hù)及其文章和關(guān)注者的信息,其中還存在很多不需要的信息茅郎。

再看一下GraphQL API的實(shí)現(xiàn):


image.png

客戶(hù)端聲明自己想要的信息蜗元,然后服務(wù)端根據(jù)請(qǐng)求返回相應(yīng)的數(shù)據(jù)

目前可見(jiàn)的優(yōu)點(diǎn):

避免了REST API中常見(jiàn)的信息過(guò)多或過(guò)少的問(wèn)題

信息過(guò)多是指,接口中總會(huì)存在客戶(hù)端不需要的信息系冗,信息過(guò)少是指單條接口無(wú)法滿(mǎn)足客戶(hù)端需求奕扣,需要請(qǐng)求多個(gè)接口才能滿(mǎn)足需要

前端可以快速迭代

在REST API中,一般都是后端定義好了API掌敬,返回固定的數(shù)據(jù)格式惯豆。當(dāng)前端業(yè)務(wù)或需求發(fā)生變化時(shí)池磁,后端很難跟上變動(dòng)的節(jié)奏。如今楷兽,業(yè)務(wù)變化已經(jīng)難以避免,所以當(dāng)前端和后端都要相應(yīng)地作出改動(dòng)芯杀,這樣效率勢(shì)必降低瘪匿。就我們公司業(yè)務(wù)來(lái)講寻馏,很多情況下,前端一兩天的改動(dòng)如果再拉上后端顽染,人多肯定要開(kāi)會(huì)再加上溝通成本的問(wèn)題粉寞,這個(gè)需求沒(méi)個(gè)一周兩周很難搞定唧垦。設(shè)想一下液样,如果在GraphQL標(biāo)準(zhǔn)下,除非大的改版坊秸,后端基本不用出人力來(lái)跟著一起需求評(píng)審褒搔,前端自己定義查詢(xún)的內(nèi)容就搞定了星瘾。

更深層次地進(jìn)行分析

當(dāng)客戶(hù)端可以選擇自己想請(qǐng)求數(shù)據(jù)的內(nèi)容時(shí)惧辈,這時(shí)候就可以分析出哪些信息是用戶(hù)感興趣的咬像,也可以更深層次地分析現(xiàn)有數(shù)據(jù)是如何被應(yīng)用的生宛。
此外陷舅,也可以分析出哪些信息用戶(hù)不再感興趣了莱睁。以上轉(zhuǎn)自騰訊云GraphQL簡(jiǎn)介

在GraphQL中芒澜,我們通過(guò)預(yù)先定義一張Schema和聲明一些Type來(lái)達(dá)到上面提及的效果痴晦,我們需要知道
  • 對(duì)于數(shù)據(jù)模型的抽象是通過(guò)Type來(lái)描述的
  • 對(duì)于接口獲取數(shù)據(jù)的邏輯是通過(guò)Schema來(lái)描述的

Type

對(duì)于數(shù)據(jù)模型的抽象是通過(guò)Type來(lái)描述的,每一個(gè)Type有若干Field組成部凑,每個(gè)Field又分別指向某個(gè)Type涂邀。
GraphQL的Type簡(jiǎn)單可以分為兩種比勉,一種叫做Scalar Type(標(biāo)量類(lèi)型)驹止,另一種叫做Object Type(對(duì)象類(lèi)型)。

Scalar Type

GraphQL中的內(nèi)建的標(biāo)量包含赡勘,String闸与、Int践樱、Float凸丸、Boolean、Enum瞭稼,對(duì)于熟悉編程語(yǔ)言的人來(lái)說(shuō),這些都應(yīng)該很好理解欲虚。
值得注意的是悔雹,GraphQL中可以通過(guò)Scalar聲明一個(gè)新的標(biāo)量腌零,比如:
prisma(一個(gè)使用GraphQL來(lái)抽象數(shù)據(jù)庫(kù)操作的庫(kù))中,還有DateTime和ID這兩個(gè)標(biāo)量分別代表日期格式和主鍵
在使用GraphQL實(shí)現(xiàn)文件上傳接口時(shí)益涧,需要聲明一個(gè)Upload標(biāo)量來(lái)代表要上傳的文件
總之,我們只需要記住饰躲,標(biāo)量是GraphQL類(lèi)型系統(tǒng)中最小的顆粒臼隔,關(guān)于它在GraphQL解析查詢(xún)結(jié)果時(shí),我們還會(huì)再提及它寄狼。

Object Type

僅有標(biāo)量是不夠的抽象一些復(fù)雜的數(shù)據(jù)模型的泊愧,這時(shí)候我們需要使用對(duì)象類(lèi)型

type Article {
  id: ID
  text: String
  isPublished: Boolean
}

上面的代碼删咱,就聲明了一個(gè)Article類(lèi)型豪筝,它有3個(gè)Field,分別是ID類(lèi)型的id敲街,String類(lèi)型的text和Boolean類(lèi)型的isPublished多艇。

對(duì)于對(duì)象類(lèi)型的Field的聲明像吻,我們一般使用標(biāo)量复隆,但是我們也可以使用另外一個(gè)對(duì)象類(lèi)型昏名,比如如果我們?cè)俾暶饕粋€(gè)新的User類(lèi)型轻局,如下:

type Article {
  id: ID
  text: String
  isPublished: Boolean
  author: User
}

Article新增的author的Field是User類(lèi)型, 代表這篇文章的作者样刷。

總之置鼻,我們通過(guò)對(duì)象模型來(lái)構(gòu)建GraphQL中關(guān)于一個(gè)數(shù)據(jù)模型的形狀,同時(shí)還可以聲明各個(gè)模型之間的內(nèi)在關(guān)聯(lián)(一對(duì)多储藐、一對(duì)一或多對(duì)多)嘶是。

mongoose

image.png
  • Schema: Mongoose 的一切始于 Schema辖源。每個(gè) schema 都會(huì)映射到一個(gè) MongoDB collection 克饶,并定義這個(gè)collection里的文檔的構(gòu)成誊辉。
    定義一個(gè)schema
const mongoose = require('mongoose');
  const Schema = mongoose.Schema;

  let blogSchema = new Schema({
    title:  String,
    author: String,
    body:   String,
    comments: [{ body: String, date: Date }],
    date: { type: Date, default: Date.now },
    hidden: Boolean,
    meta: {
      votes: Number,
      favs:  Number
    }
  });
  • Model: 基本文檔數(shù)據(jù)的父類(lèi),通過(guò)集成Schema定義的基本方法和屬性得到相關(guān)的內(nèi)容.
    Models 是從 Schema 編譯來(lái)的構(gòu)造函數(shù)堕澄。 它們的實(shí)例就代表著可以從數(shù)據(jù)庫(kù)保存和讀取的 documents。 從數(shù)據(jù)庫(kù)創(chuàng)建和讀取 document 的所有操作都是通過(guò) model 進(jìn)行的坞嘀。
var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var Tank = mongoose.model('Tank', schema);

第一個(gè)參數(shù)是跟 model 對(duì)應(yīng)的集合( collection )名字的 單數(shù) 形式丽涩。 Mongoose 會(huì)自動(dòng)找到名稱(chēng)是 model 名字 復(fù)數(shù) 形式的 collection 。 對(duì)于上例继准,Tank 這個(gè) model 就對(duì)應(yīng)數(shù)據(jù)庫(kù)中 tanks 這個(gè) collection矮男。.model() 這個(gè)函數(shù)是對(duì) schema 做了拷貝(生成了 model)。 你要確保在調(diào)用 .model() 之前把所有需要的東西都加進(jìn) schema 里了崔泵!

  • instance: 這就是實(shí)實(shí)在在的數(shù)據(jù)了. 通過(guò) new Model()初始化得到.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末憎瘸,一起剝皮案震驚了整個(gè)濱河市幌甘,隨后出現(xiàn)的幾起案子锅风,更是在濱河造成了極大的恐慌,老刑警劉巖皱埠,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泪姨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肮砾,警方通過(guò)查閱死者的電腦和手機(jī)仗处,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)吃环,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洋幻,“玉大人,你說(shuō)我怎么就攤上這事竭沫∑锔荩” “怎么了靶端?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵杨名,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我姐霍,道長(zhǎng)镊折,這世上最難降的妖魔是什么介衔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任炎咖,我火速辦了婚禮乘盼,結(jié)果婚禮上绸栅,老公的妹妹穿的比我還像新娘。我一直安慰自己粹胯,他們只是感情好风纠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布镐捧。 她就那樣靜靜地躺著愤估,像睡著了一般玩焰。 火紅的嫁衣襯著肌膚如雪昔园。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音荤西,去河邊找鬼勉躺。 笑死觅丰,一個(gè)胖子當(dāng)著我的面吹牛妇萄,可吹牛的內(nèi)容都是我干的冠句。 我是一名探鬼主播轩端,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼壳影!你這毒婦竟也來(lái)了宴咧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纳猪,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后桃笙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體氏堤,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年搏明,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鼠锈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡星著,死狀恐怖购笆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虚循,我是刑警寧澤同欠,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站横缔,受9級(jí)特大地震影響行您,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剪廉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一捌斧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姓迅,春花似錦、人聲如沸解寝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)说铃。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚓峦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工召夹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲸阔。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓死讹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笤虫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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