日本电影一区二区_日本va欧美va精品发布_日本黄h兄妹h动漫一区二区三区_日本欧美黄色

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

2015年,F(xiàn)acebook推出了GraphQL(Graph-Query-Language)查詢語言。到目前為止,IBM、Twitter、Walmart Labs、紐約時(shí)報(bào)、Coursera等很多公司已經(jīng)在內(nèi)部從RESTful轉(zhuǎn)向GraphQL API。

作為一種查詢語言,GraphQL具有以下特點(diǎn):

(1)無需關(guān)心如何更新文檔,所有的查詢(query)和變更會(huì)自動(dòng)形成文檔(cchema)。

(2)無需獲取整個(gè)數(shù)據(jù)集,通過schema與resolver(處理器)之間的映射關(guān)系,由對(duì)應(yīng)的resolver去獲取數(shù)據(jù),將結(jié)果返回給前端,從而可以編寫僅僅返回所請(qǐng)求數(shù)據(jù)的查詢。

(3)對(duì)前端提供統(tǒng)一的訪問點(diǎn)。從不同的API中獲取數(shù)據(jù)并非易事,GraphQL支持將所有API進(jìn)行拼接。

愛奇藝號(hào)技術(shù)團(tuán)隊(duì)在實(shí)施微服務(wù)化的過程中,受到Forrester Research提出的低代碼開發(fā)(Low-Code:即無需編碼或通過少量代碼就可以快速生成應(yīng)用程序的開發(fā)理念)的啟發(fā),基于GraphQL構(gòu)建BFF(Backend for Frontends),幫助開發(fā)人員用拖拽式操作,直觀地創(chuàng)建出一個(gè)供前端調(diào)用的API,本文將對(duì)實(shí)施過程中的經(jīng)驗(yàn)總結(jié)進(jìn)行敘述。

GraphQL介紹

與 RESTful API 一樣,GraphQL API設(shè)計(jì)用于處理 HTTP 請(qǐng)求并為這些請(qǐng)求提供響應(yīng)。REST API 構(gòu)建在請(qǐng)求方法和端點(diǎn)之間的連接上,而 GraphQL API 被設(shè)計(jì)為只通過一個(gè)端點(diǎn),始終使用 POST 請(qǐng)求進(jìn)行查詢,其 URL 通常是xxx.com/graphql。圖1-1為GraphQL部署架構(gòu)圖,可以看到它處于系統(tǒng)“中間層”。

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖1-1

GraphQL 全稱叫 Graph Query Language,官方宣傳語是“為你的 API 量身定制的查詢語言”,用傳統(tǒng)的方式來解釋就是:將你所有后端 API 組成的集合看成一個(gè)數(shù)據(jù)庫,用戶終端發(fā)送一個(gè)查詢語句,你的 GraphQL 服務(wù)解析這條語句并通過一系列規(guī)則從你的“API 數(shù)據(jù)庫”里面將查詢的數(shù)據(jù)結(jié)果返回給終端,而 GraphQL 就相當(dāng)于這個(gè)系統(tǒng)的一個(gè)查詢語言,像 SQL 之于 MySQL 一樣。GraphQL執(zhí)行過程如圖1-2所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖1-2

圖1-2是GraphQL 執(zhí)行的大致流程,第一步去驗(yàn)證查詢語句是否符合GraphQL的schema規(guī)范,確認(rèn)查詢內(nèi)容的合法性,第二步生成執(zhí)行的上下文,關(guān)鍵點(diǎn)在第三步和第四步,第三步是獲取查詢語句所需要查詢的字段,這里叫 fields,所有需要查詢的字段可以在查詢語句里拿到,這就是 GraphQL 如何做到避免返回冗余數(shù)據(jù)的。拿到所有需要查詢的字段后,第四步針對(duì)每一個(gè)字段去執(zhí)行它的 resolver,可以從 resolver 返回的數(shù)據(jù)里面拿到字段對(duì)應(yīng)的數(shù)據(jù),最后是格式化結(jié)果并返回。

重點(diǎn)是第四步,展開說明一下,如圖1-3、圖1-4所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖1-3

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖1-4

在GraphQL里面有一個(gè)概念叫類型 (type),每一個(gè)類型下面對(duì)應(yīng)的是一個(gè)或多個(gè)字段(field),每個(gè)字段都會(huì)綁定一個(gè)處理器(resolver),這個(gè) resolver 的作用就是獲取字段對(duì)應(yīng)的數(shù)據(jù)。

對(duì)應(yīng)到圖1-4所示,UserInfo這個(gè)類型,它有三個(gè)字段:nickName、contractNo、fansNumber。每個(gè)字段都對(duì)應(yīng)一個(gè)resolver,resolver 需要被開發(fā)者重新定義,否則會(huì)報(bào)錯(cuò)。所以UserInfo下的三個(gè)字段nickName、contractNo、fansNumber需要通過實(shí)現(xiàn)各自resolver來分別從用戶微服務(wù)、合同微服務(wù)、粉絲微服務(wù)去獲取用戶信息、合同信息和粉絲信息,然后再聚合返回,這樣就達(dá)到了使用 GraphQL 進(jìn)行數(shù)據(jù)拼接的目的。

BFF架構(gòu)

愛奇藝號(hào)在實(shí)施微服務(wù)化的過程中,加入了BFF的前后端架構(gòu),如圖2-1所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖2-1

從圖中可以看出,BFF作為前后端的中間層服務(wù)。主要的業(yè)務(wù)邏輯都封裝在BFF層,前端通過BFF進(jìn)行訪問,減少微服務(wù)之間的相互調(diào)用。BFF層通過REST API方式提供服務(wù),隨著服務(wù)的增多,提供的接口越來越多,這會(huì)導(dǎo)致REST API越來越冗余。對(duì)于前端而言,有的API粒度較粗不滿足需求;有的API又粒度太細(xì),不僅增加了響應(yīng)時(shí)間,還會(huì)造成流量的浪費(fèi)。對(duì)于后端而言,前端需要的數(shù)據(jù)往往在不同的地方具有相似性,但卻又不盡相同,比如:針對(duì)用戶信息,有些地方需要用戶簡(jiǎn)要的基礎(chǔ)信息和詳細(xì)的視頻信息,而有些地方卻需要用戶詳細(xì)的基礎(chǔ)信息和簡(jiǎn)要的視頻信息。這往往需要開發(fā)不同的接口去滿足各種定制需求,增加了開發(fā)人員的工作量,提升了開發(fā)工作的重復(fù)度。

  • GraphQL與Rest API對(duì)比:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

表2-1

從表2-1中的對(duì)比可以看出,GraphQL相對(duì)于Rest API方式,性能更好,能有效減少前后端開發(fā)溝通成本。但是Facebook的官方只有JS版本實(shí)現(xiàn),查詢方式和Rest API也有所不同(如表2-2所示),對(duì)于老項(xiàng)目有一定的遷移、學(xué)習(xí)成本。

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

表2-2

接下來,本文將主要探討如何基于graphql-Java,做到減少遷移成本的同時(shí),又能提升后端開發(fā)人員的效率,避免重復(fù)開發(fā)。

愛奇藝號(hào)API生成平臺(tái)實(shí)踐

愛奇藝號(hào)API生成平臺(tái),是一個(gè)低代碼平臺(tái)。由于愛奇藝號(hào)的技術(shù)棧主要基于Java,所以使用的是GraphQL的 Java實(shí)現(xiàn)。基于graphql-java,API生成平臺(tái)主要做了以下功能優(yōu)化及增強(qiáng)。

(1)支持Rest API:降低前端接入成本。

(2)動(dòng)態(tài)接入監(jiān)控:動(dòng)態(tài)生成的API,與其他普通接口一樣支持Prometheus監(jiān)控,保證監(jiān)控的靈活性和服務(wù)的穩(wěn)定性。

(3)靈活配置:可以動(dòng)態(tài)生成GraphQL的schema,方便后端接入新服務(wù)。

(4)可視化API管理平臺(tái):API接口提供可視化操作,方便查看、新增、修改和重用。

接下來將對(duì)以上功能進(jìn)行詳細(xì)介紹:

1.支持Rest API

graphql-java通過Spring的封裝,位于整個(gè)架構(gòu)的網(wǎng)關(guān)層或BFF層。項(xiàng)目user-info-graphQL依賴graphql-java-spring,支持Rest API請(qǐng)求。平臺(tái)的整體架構(gòu)圖如圖3-1所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-1

User-info-graphQL的服務(wù)流程圖如圖3-2所示。客戶端通過graphql/前綴的Rest API方式請(qǐng)求,后端通過前綴與GraphQL Query綁定,從DB獲取映射關(guān)系,最終轉(zhuǎn)換成GraphQL支持的查詢語法。

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-2

2.動(dòng)態(tài)接入監(jiān)控

在user-info-graphQL項(xiàng)目中,原本是通過template url來匹配任意自定義url;導(dǎo)致監(jiān)控平臺(tái)只能顯示template url的請(qǐng)求信息,如圖3-3所示。這個(gè)問題可以通過重寫spring-boot-actuator中獲取tags的方法,將真實(shí)的url請(qǐng)求信息暴露到Spring boot的/actuator/prometheus端點(diǎn)這個(gè)方法來解決,如圖3-4所示。

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-3

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-4

通過暴露的監(jiān)控端點(diǎn)接入Prometheus,實(shí)現(xiàn)對(duì)新生成的API進(jìn)行實(shí)時(shí)動(dòng)態(tài)監(jiān)控,示例效果如圖3-5所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-5

3.靈活配置

為了方便后端快速接入新增微服務(wù),達(dá)到支持API動(dòng)態(tài)擴(kuò)展目的。項(xiàng)目中通過Velocity定義schema模板,通過Java注解、反射機(jī)制動(dòng)態(tài)生成graphqls模板文件,如圖3-6所示:

減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?減少重復(fù)開發(fā),GraphQL在低代碼平臺(tái)如何落地?

圖3-6

圖3-6中的GraphQL schema模板,支持通過用戶UID查詢用戶信息。用戶信息是由多個(gè)微服務(wù)聚合而成,采用異步調(diào)用多個(gè)微服務(wù)并行獲取數(shù)據(jù)?;诖四0澹脩糁恍枰獙?shí)現(xiàn)SPI定義好的接口,就能實(shí)現(xiàn)對(duì)新增微服務(wù)的支持。
4.可視化API管理平臺(tái) 通過API生成管理平臺(tái),開發(fā)人員可以實(shí)現(xiàn)API接口的可視化配置、生成、動(dòng)態(tài)監(jiān)控等功能,達(dá)到開箱即用的效果,極大提升開發(fā)和運(yùn)維效率。

總結(jié)

通過GraphQL動(dòng)態(tài)構(gòu)建BFF服務(wù)層API,聚合不同的微服務(wù),相比于Rest API方式,能夠減少后端重復(fù)開發(fā),加快響應(yīng)前端需求。后端開發(fā)人員只需要開發(fā)維護(hù)新增微服務(wù),并通過SPI方式,增加BFF層對(duì)新增微服務(wù)的支持即可。
價(jià) 值:通過在愛奇藝號(hào)后端微服務(wù)引入GraphQL構(gòu)建BFF服務(wù)層,可以達(dá)成以下效果:

開發(fā)方面的優(yōu)勢(shì)

  • 提升開發(fā)效率:后端開發(fā)人員職責(zé)分工明確,微服務(wù)與BFF層獨(dú)立開發(fā)及維護(hù)。新增微服務(wù)接入方便,因BFF層對(duì)外的API支持動(dòng)態(tài)生成,所以無需更改BFF層的代碼,只需集中維護(hù)微服務(wù)。前端可以通過GraphQL的schema查看接口返回?cái)?shù)據(jù),減少前后端溝通成本。
  • 形成低代碼平臺(tái):隨著構(gòu)建的微服務(wù)基礎(chǔ)措施足夠完善,BFF層支持動(dòng)態(tài)生成API接口,極大減輕重復(fù)工作量。

運(yùn)行維護(hù)時(shí)的優(yōu)勢(shì)

  • 便于監(jiān)控:新增BFF層API接口,通過支持Prometheus端點(diǎn)監(jiān)控,無開發(fā)成本。
  • 支持系統(tǒng)高吞吐量:BFF服務(wù)、微服務(wù)都是基于docker部署,支持QPS動(dòng)態(tài)擴(kuò)容,能夠支持高并發(fā)。
  • 便于維護(hù)和擴(kuò)展:基于GraphQL構(gòu)建的BFF層,API接口動(dòng)態(tài)生成,層次清晰,更易維護(hù)、擴(kuò)展。

難 點(diǎn):

  • 動(dòng)態(tài)擴(kuò)展查詢支持,目前schema的定義都是基于明確字段的情況下,如果需要支持動(dòng)態(tài)的查詢支持,需要支持動(dòng)態(tài)schema擴(kuò)展和解析。
  • 中文文檔少,F(xiàn)acebook官方只發(fā)布了JS實(shí)現(xiàn),Java實(shí)現(xiàn)都是基于開源社區(qū),文檔和功能都不是很完善。

未來規(guī)劃:

隨著BFF端對(duì)API請(qǐng)求的多樣化,需要?jiǎng)討B(tài)支持新方法擴(kuò)展及監(jiān)控。目前API與請(qǐng)求的映射關(guān)系持久化在MySQL中,需要支持集群和高性能,后續(xù)逐步遷移到ZK或Redis中,并緩存到本地。


隨著云原生和K8s的興起,基于K8s部署的Go服務(wù),更易擴(kuò)容和維護(hù)?;贘ava實(shí)現(xiàn)的GraphQL,如果遷移到K8s上部署,很難實(shí)現(xiàn)快速擴(kuò)縮容的效果。而graphql-go在github上的star高達(dá)7k,可見熱度極高。如果基于Go實(shí)現(xiàn)BFF端,API與請(qǐng)求的映射關(guān)系可以存儲(chǔ)于K8s的Pod配置文件中,并且通過一個(gè)API部署一類Pod,進(jìn)行服務(wù)隔離,可以更高程度的保證服務(wù)穩(wěn)定。

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號(hào)
公眾號(hào)
在線咨詢
分享本頁
返回頂部
依安县| 永嘉县| 桑日县| 荆门市| 凭祥市| 顺昌县| 平武县| 开江县| 浦江县| 泽库县| 巴东县| 东方市| 平顶山市| 集贤县| 横峰县| 紫阳县| 长岭县| 乐清市| 昌都县| 鲁山县| 元氏县| 织金县| 康马县| 普安县| 留坝县| 自治县| 井研县| 永清县| 宁明县| 海南省| 沭阳县| 关岭| 电白县| 上蔡县| 方正县| 安乡县| 旬邑县| 黄龙县| 确山县| 柳林县| 白水县|