您好,登錄后才能下訂單哦!
GraphQL是什么
.net下如何運(yùn)用GraphQL
運(yùn)用GraphQL調(diào)用Github api
結(jié)語(yǔ)
最近在折騰使用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ù)展開(kāi)了。關(guān)于egde和node在下文會(huì)有少許講解。對(duì)GraphQL有興趣進(jìn)行更深入了解的可以自行研究學(xué)習(xí),我自己也是剛?cè)腴T(mén),不坑大家了:),官網(wǎng)是http://graphql.org/(這個(gè)可能打不開(kāi),可以打開(kāi)國(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ù),而且沒(méi)有任何冗余,也讓 API 更容易地隨著時(shí)間推移而演進(jìn),還能用于構(gòu)建強(qiáng)大的開(kāi)發(fā)者工具。
由于我需要做一個(gè)定時(shí)任務(wù)將github上的數(shù)據(jù)定時(shí)拉到本地,所以自然的選擇了后端處理的方式。找了一下.net下的GraphQL客戶端,用了這個(gè)graphql-client。代碼如下:
var heroRequest = new GraphQLRequest { Query = graphql //這里填寫(xiě)query的內(nèi)容。 };var graphQLClient = new GraphQLClient("https://api.github.com/graphql"); graphQLClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("Safari", "537.36")); //上面這行很關(guān)鍵,UserAgent一定要寫(xiě)上,要不然會(huì)出現(xiàn)403錯(cuò)誤,花了好久才找到這個(gè)問(wèn)題。 graphQLClient.DefaultRequestHeaders.Add("Authorization", "bearer token"); //這里的token是個(gè)占位,實(shí)際需要在Github上生成。var graphQLResponse = graphQLClient.PostAsync(heroRequest).Result;
關(guān)于token的生成以及其它的一些環(huán)境準(zhǔn)備工作,在github上有詳細(xì)的描述,參見(jiàn):https://developer.github.com/v4/guides/forming-calls/#authenticating-with-graphql。
重要的事情說(shuō)3遍:UserAgent一定要寫(xiě)上??! UserAgent一定要寫(xiě)上?。?nbsp;UserAgent一定要寫(xiě)上??!
Github提供的API和相關(guān)文檔在https://developer.github.com/v4/ 右側(cè)的目錄樹(shù)上,這次筆者需要拉取github的大量repository庫(kù),所以用到的search接口(但是很奇怪,這個(gè)接口在文檔中并沒(méi)有列出來(lái),也不知道為什么)。建議大家可以先在Github提供的explorer中先測(cè)試和驗(yàn)證,OK了在把代碼寫(xiě)到實(shí)際的項(xiàng)目中。
接著,筆者在實(shí)現(xiàn)自己需要的功能時(shí)又學(xué)習(xí)了2個(gè)概念,才能正常開(kāi)展下面的工作。第一個(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)類(lèi)型的,所以當(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在配置文件中自行替換即可。
最后附帶提一下,GraphQL的出現(xiàn),主要的場(chǎng)景還是在于賦能前端開(kāi)發(fā),賦予了前端開(kāi)發(fā)者自由組織和定制請(qǐng)求數(shù)據(jù)的能力。這是一個(gè)將前后端分離后的界限偏向前端的框架,所以直接在前端通過(guò)GraphQL訪問(wèn)后端數(shù)據(jù)是個(gè)人比較推崇的方式。目前前端非?;馃岬腉raphQL框架也不少,主流的就是下面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ā)、聚合和性能等問(wèn)題。
作者:Zachary_Fan
出處:http://www.cnblogs.com/Zachary-Fan/p/CsharpGraphql.html
如果你想及時(shí)得到個(gè)人自寫(xiě)文章的消息推送,歡迎掃描下面的二維碼~。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。