記一次通過(guò)c#運(yùn)用GraphQL調(diào)用Github api

如果這是第二次看到我的文章妖爷,歡迎訂閱z哥的公眾號(hào)(跨界架構(gòu)師)哦~

每周五11:45 按時(shí)送達(dá)霞玄。當(dāng)然了窜司,也會(huì)時(shí)不時(shí)加個(gè)餐~

一、Graphql是什么

  最近在折騰使用Github api做個(gè)微信小程序練練手蹲坷,本篇文章就是在這個(gè)過(guò)程中記錄驶乾。

  直接先看下GraphQL的語(yǔ)法風(fēng)格,感受一下:

query {

? repository(owner:"octocat", name:"Hello-World") {

? ? ? id

? }

}

  這是最最最簡(jiǎn)單的一個(gè)運(yùn)用示例循签,效果上等價(jià)于http://graphqlapi.xxx.com/query/repository?owner=octocat&name=Hello-World 级乐,返回的內(nèi)容格式是這樣:

{

? "data": {

? ? "repository": {

? ? ? "id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5"? ? }

? }

}

  再看下稍微復(fù)雜點(diǎn)的查詢方式:

query {

? repository(owner:"octocat", name:"Hello-World") {

? ? issues(last:20, states:CLOSED) {

? ? ? edges {

? ? ? ? node {

? ? ? ? ? title

? ? ? ? ? url

? ? ? ? ? labels(first:5) {

? ? ? ? ? ? edges {

? ? ? ? ? ? ? node {

? ? ? ? ? ? ? ? name

? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? }

? ? ? }

? ? }

? }

}

????????這是一個(gè)多級(jí)對(duì)象嵌套的查詢,這里就不繼續(xù)展開了县匠。關(guān)于egde和node在下文會(huì)有少許講解风科。對(duì)GraphQL有興趣進(jìn)行更深入了解的可以自行研究學(xué)習(xí),我自己也是剛?cè)腴T乞旦,不坑大家了:)贼穆,官網(wǎng)是http://graphql.org/(這個(gè)可能打不開,可以打開國(guó)內(nèi)的地址http://graphql.cn)杆查,F(xiàn)acebook發(fā)布的規(guī)范在http://facebook.github.io/graphql/October2016/

  GraphQL 既是一種用于 API 的查詢語(yǔ)言也是一個(gè)滿足你數(shù)據(jù)查詢的運(yùn)行時(shí)臀蛛。GraphQL 對(duì)你的 API 中的數(shù)據(jù)提供了一套易于理解的完整描述亲桦,使得客戶端能夠準(zhǔn)確地獲得它需要的數(shù)據(jù),而且沒有任何冗余浊仆,也讓 API 更容易地隨著時(shí)間推移而演進(jìn)客峭,還能用于構(gòu)建強(qiáng)大的開發(fā)者工具。


二抡柿、.net下如何運(yùn)用GraphQL

????????由于我需要做一個(gè)定時(shí)任務(wù)將github上的數(shù)據(jù)定時(shí)拉到本地舔琅,所以自然的選擇了后端處理的方式。找了一下.net下的GraphQL客戶端洲劣,用了這個(gè)graphql-client备蚓。代碼如下:

varheroRequest =new GraphQLRequest

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? Query = graphql? //這里填寫query的內(nèi)容课蔬。

? ? ? ? ? ? ? ? };vargraphQLClient =newGraphQLClient("https://api.github.com/graphql");graphQLClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Safari", "537.36"));

//上面這行很關(guān)鍵,UserAgent一定要寫上郊尝,要不然會(huì)出現(xiàn)403錯(cuò)誤二跋,花了好久才找到這個(gè)問題。

graphQLClient.DefaultRequestHeaders.Add(

"Authorization","bearertoken");? //這里的token是個(gè)占位流昏,實(shí)際需要在Github上生成扎即。vargraphQLResponse = graphQLClient.PostAsync(heroRequest).Result;

關(guān)于token的生成以及其它的一些環(huán)境準(zhǔn)備工作,在github上有詳細(xì)的描述况凉,參見:https://developer.github.com/v4/guides/forming-calls/#authenticating-with-graphql谚鄙。

重要的事情說(shuō)3遍:UserAgent一定要寫上!刁绒!?UserAgent一定要寫上C朴!?UserAgent一定要寫上L哦А粮坞!


三、運(yùn)用GraphQL調(diào)用Github api

????????Github提供的API和相關(guān)文檔在https://developer.github.com/v4/?右側(cè)的目錄樹上初狰,這次筆者需要拉取github的大量repository庫(kù)莫杈,所以用到的search接口(但是很奇怪,這個(gè)接口在文檔中并沒有列出來(lái)奢入,也不知道為什么)筝闹。建議大家可以先在Github提供的explorer中先測(cè)試和驗(yàn)證,OK了在把代碼寫到實(shí)際的項(xiàng)目中腥光。

  接著关顷,筆者在實(shí)現(xiàn)自己需要的功能時(shí)又學(xué)習(xí)了2個(gè)概念,才能正常開展下面的工作武福。第一個(gè)是edge與node的概念议双,edge可以理解為一個(gè)分頁(yè)對(duì)象,其中除了包含實(shí)際的數(shù)據(jù)外還有一個(gè)cursor(返回的每條數(shù)據(jù)的唯一標(biāo)識(shí)捉片,如果要分頁(yè)的話用得到這個(gè)數(shù)據(jù)平痰,配合before與after關(guān)鍵字來(lái)使用)字段,實(shí)際數(shù)據(jù)就是用node表示的伍纫。

????????另外GraphQL是強(qiáng)類型的宗雇,所以當(dāng)筆者用到的search返回的結(jié)果并不是一個(gè)明確的數(shù)據(jù)對(duì)象時(shí),先需要通過(guò)node下的__typename字段來(lái)獲得實(shí)際的對(duì)象是什么莹规。代碼如下:

query {

? search(query:"language:c#",type:REPOSITORY,first:1){? ? edges{? ? ? cursor,? ? ? node{__typename}? ? }? }}

  得到的結(jié)果是:

{

? "data": {

? ? "search": {

? ? ? "edges": [

? ? ? ? {

? ? ? ? ? "cursor": "Y3Vyc29yOjE=",

? ? ? ? ? "node": {

? ? ? ? ? ? "__typename": "Repository"? ? ? ? ? }

? ? ? ? }

? ? ? ]

? ? }

? }

}

????????得到的實(shí)際的數(shù)據(jù)對(duì)象是Repository之后赔蒲,通過(guò)查閱Github Api的文檔得到該對(duì)象有哪些字段,并且從中選擇需要的字段即可。這個(gè)就是GraphQL的設(shè)計(jì)天然優(yōu)勢(shì)之一舞虱,按需獲取欢际。單在接下去運(yùn)用的時(shí)候又需要引入一個(gè)新的概念fragment,這個(gè)可以理解為一個(gè)模板砾嫉,通過(guò)這個(gè)模板來(lái)向服務(wù)端指明需要獲取的數(shù)據(jù)字段幼苛。代碼如下:

fragment repFragment on Repository {

? name,

? forkCount,

? url,

? createdAt,

? updatedAt,

? licenseInfo{? //對(duì)象嵌套

? ? nickname? ? //licenseInfo的nickname字段

? },

? stargazers{? //對(duì)象嵌套

? ? totalCount? //stargazers的totalCount字段

? }

}

query {

? search(query:"language:c#",type:REPOSITORY,first:100){

? ? edges{

? ? ? cursor,

? ? ? node{

? ? ? ? __typename

? ? ? ? ...repFragment

? ? ? }

? ? }

? }

}

?  好了,這樣就得到我需要的結(jié)果了焕刮。

下面附上筆者做的Demo:https://github.com/ZacharyFan/GitHubRanking舶沿,其中的token在配置文件中自行替換即可。


四配并、結(jié)語(yǔ)

????????最后附帶提一下括荡,GraphQL的出現(xiàn),主要的場(chǎng)景還是在于賦能前端開發(fā)溉旋,賦予了前端開發(fā)者自由組織和定制請(qǐng)求數(shù)據(jù)的能力畸冲。這是一個(gè)將前后端分離后的界限偏向前端的框架,所以直接在前端通過(guò)GraphQL訪問后端數(shù)據(jù)是個(gè)人比較推崇的方式观腊。目前前端非骋叵校火熱的GraphQL框架也不少,主流的就是下面2個(gè):apollo(https://github.com/apollographql/apollo-client)梧油、relay(https://github.com/facebook/relay)苫耸。

  GraphQL雖好,但是要真正在中大型項(xiàng)目中運(yùn)用GraphQL儡陨,還有有很大的困難的褪子,服務(wù)端需要支持到GraphQL的規(guī)范格式進(jìn)行數(shù)據(jù)輸出,我認(rèn)為需要付出的成本可不小骗村。哪怕的架設(shè)一層中間層嫌褪,也需要解決諸如分發(fā)、聚合和性能等問題胚股。



?作者:Zachary(個(gè)人微信號(hào):Zachary-ZF)

微信公眾號(hào)(首發(fā)):跨界架構(gòu)師笼痛。<-- 點(diǎn)擊查閱近期熱門文章

如果你是初級(jí)程序員,想提升但不知道如何下手琅拌。又或者做程序員多年缨伊,陷入了一些瓶頸想拓寬一下視野。歡迎關(guān)注我的公眾號(hào)「跨界架構(gòu)師」财忽,回復(fù)「技術(shù)」倘核,送你一份我長(zhǎng)期收集和整理的思維導(dǎo)圖泣侮。

如果你是運(yùn)營(yíng)即彪,面對(duì)不斷變化的市場(chǎng)束手無(wú)策。又或者想了解主流的運(yùn)營(yíng)策略,以豐富自己的“倉(cāng)庫(kù)”隶校。歡迎關(guān)注我的公眾號(hào)「跨界架構(gòu)師」漏益,回復(fù)「運(yùn)營(yíng)」,送你一份我長(zhǎng)期收集和整理的思維導(dǎo)圖深胳。

定期發(fā)表原創(chuàng)內(nèi)容:架構(gòu)設(shè)計(jì)丨分布式系統(tǒng)丨產(chǎn)品丨運(yùn)營(yíng)丨一些深度思考绰疤。

掃碼加入小圈子??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舞终,隨后出現(xiàn)的幾起案子轻庆,更是在濱河造成了極大的恐慌,老刑警劉巖敛劝,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件余爆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡夸盟,警方通過(guò)查閱死者的電腦和手機(jī)蛾方,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)上陕,“玉大人桩砰,你說(shuō)我怎么就攤上這事∈筒荆” “怎么了亚隅?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辕万。 經(jīng)常有香客問我枢步,道長(zhǎng),這世上最難降的妖魔是什么渐尿? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任醉途,我火速辦了婚禮,結(jié)果婚禮上砖茸,老公的妹妹穿的比我還像新娘隘擎。我一直安慰自己,他們只是感情好凉夯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布货葬。 她就那樣靜靜地躺著,像睡著了一般劲够。 火紅的嫁衣襯著肌膚如雪震桶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天征绎,我揣著相機(jī)與錄音蹲姐,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛柴墩,可吹牛的內(nèi)容都是我干的忙厌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼江咳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逢净!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起歼指,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤爹土,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后踩身,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體着饥,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年惰赋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宰掉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赁濒,死狀恐怖轨奄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拒炎,我是刑警寧澤挪拟,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站击你,受9級(jí)特大地震影響玉组,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜丁侄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一惯雳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸿摇,春花似錦石景、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至筷黔,卻和暖如春往史,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佛舱。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工椎例, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揽乱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓粟矿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親损拢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子陌粹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 作者: 一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-13】 更新日志 導(dǎo)入 作為一種強(qiáng)大的DSQL,學(xué)習(xí)GraphQL...
    一字馬胡閱讀 11,006評(píng)論 0 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理福压,服務(wù)發(fā)現(xiàn)掏秩,斷路器,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 他是此王朝的太子荆姆,她是丞相府里任性的嫡女蒙幻。 那年,因?yàn)橐淮窝鐣?huì)胆筒,她見他邮破,一見鐘情。 自此仆救, 她便明里暗里的打探關(guān)于...
    是小道白啊閱讀 171評(píng)論 0 0
  • 忙碌的一天抒和。 床上瞬間回顧過(guò)去十年,再次感到立場(chǎng)的重要性彤蔽。中午摧莽、晚上餐桌,不知不覺又吃多了顿痪,如果說(shuō)喝酒是氛圍的事情...
    天之心語(yǔ)閱讀 236評(píng)論 0 0
  • 企業(yè)要使用工單進(jìn)行核銷镊辕,那就必須使用數(shù)據(jù)系統(tǒng)與海關(guān)進(jìn)行對(duì)接,將公司的進(jìn)蚁袭、出征懈、轉(zhuǎn)、存數(shù)據(jù)均按報(bào)文拋送給海關(guān)揩悄,海關(guān)按接...
    江黎Nicole閱讀 1,063評(píng)論 0 1