【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

减少重复开发,GraphQL 在低代码平台如何落地?

  • 2021-02-02
  • 本文字数:3480 字

    阅读完需:约 11 分钟

减少重复开发,GraphQL在低代码平台如何落地?

2015 年,Facebook 推出了 GraphQL(Graph-Query-Language)查询语言。到目前为止,IBM、Twitter、Walmart Labs、纽约时报、Coursera 等很多公司已经在内部从 RESTful 转向 GraphQL API


作为一种查询语言,GraphQL 具有以下特点:

(1)无需关心如何更新文档,所有的查询(query)和变更会自动形成文档(cchema)


(2)无需获取整个数据集,通过 schema 与 resolver(处理器)之间的映射关系,由对应的 resolver 去获取数据,将结果返回给前端,从而可以编写仅仅返回所请求数据的查询。


(3)对前端提供统一的访问点。从不同的 API 中获取数据并非易事,GraphQL 支持将所有 API 进行拼接


爱奇艺号技术团队在实施微服务化的过程中,受到 Forrester Research 提出的低代码开发(Low-Code:即无需编码或通过少量代码就可以快速生成应用程序的开发理念)的启发,基于 GraphQL 构建 BFF(Backend for Frontends),帮助开发人员用拖拽式操作,直观地创建出一个供前端调用的 API,本文将对实施过程中的经验总结进行叙述。


GraphQL 介绍

与 RESTful API 一样,GraphQL API 设计用于处理 HTTP 请求并为这些请求提供响应。REST API 构建在请求方法和端点之间的连接上,而 GraphQL API 被设计为只通过一个端点,始终使用 POST 请求进行查询,其 URL 通常是 xxx.com/graphql。图 1-1 为 GraphQL 部署架构图,可以看到它处于系统“中间层”


图 1-1

GraphQL 全称叫 Graph Query Language,官方宣传语是“为你的 API 量身定制的查询语言”,用传统的方式来解释就是:将你所有后端 API 组成的集合看成一个数据库,用户终端发送一个查询语句,你的 GraphQL 服务解析这条语句并通过一系列规则从你的“API 数据库”里面将查询的数据结果返回给终端,而 GraphQL 就相当于这个系统的一个查询语言,像 SQL 之于 MySQL 一样。GraphQL 执行过程如图 1-2 所示:


图 1-2

图 1-2 是 GraphQL 执行的大致流程,第一步去验证查询语句是否符合 GraphQL 的 schema 规范,确认查询内容的合法性,第二步生成执行的上下文,关键点在第三步和第四步,第三步是获取查询语句所需要查询的字段,这里叫 fields,所有需要查询的字段可以在查询语句里拿到,这就是 GraphQL 如何做到避免返回冗余数据的。拿到所有需要查询的字段后,第四步针对每一个字段去执行它的 resolver,可以从 resolver 返回的数据里面拿到字段对应的数据,最后是格式化结果并返回。


重点是第四步,展开说明一下,如图 1-3、图 1-4 所示:



图 1-3



图 1-4


在 GraphQL 里面有一个概念叫类型 (type),每一个类型下面对应的是一个或多个字段(field),每个字段都会绑定一个处理器(resolver),这个 resolver 的作用就是获取字段对应的数据


对应到图 1-4 所示,UserInfo 这个类型,它有三个字段:nickName、contractNo、fansNumber。每个字段都对应一个 resolver,resolver 需要被开发者重新定义,否则会报错。所以 UserInfo 下的三个字段 nickName、contractNo、fansNumber 需要通过实现各自 resolver 来分别从用户微服务、合同微服务、粉丝微服务去获取用户信息、合同信息和粉丝信息,然后再聚合返回,这样就达到了使用 GraphQL 进行数据拼接的目的


BFF 架构

爱奇艺号在实施微服务化的过程中,加入了 BFF 的前后端架构,如图 2-1 所示:



图 2-1

从图中可以看出,BFF 作为前后端的中间层服务。主要的业务逻辑都封装在 BFF 层,前端通过 BFF 进行访问,减少微服务之间的相互调用。BFF 层通过 REST API 方式提供服务,随着服务的增多,提供的接口越来越多,这会导致 REST API 越来越冗余。对于前端而言,有的 API 粒度较粗不满足需求;有的 API 又粒度太细,不仅增加了响应时间,还会造成流量的浪费。对于后端而言,前端需要的数据往往在不同的地方具有相似性,但却又不尽相同,比如:针对用户信息,有些地方需要用户简要的基础信息和详细的视频信息,而有些地方却需要用户详细的基础信息和简要的视频信息。这往往需要开发不同的接口去满足各种定制需求,增加了开发人员的工作量,提升了开发工作的重复度。


  • GraphQL 与 Rest API 对比:


表 2-1


从表 2-1 中的对比可以看出,GraphQL 相对于 Rest API 方式,性能更好,能有效减少前后端开发沟通成本。但是 Facebook 的官方只有 JS 版本实现,查询方式和 Rest API 也有所不同(如表 2-2 所示),对于老项目有一定的迁移、学习成本。



表 2-2


接下来,本文将主要探讨如何基于 graphql-java,做到减少迁移成本的同时,又能提升后端开发人员的效率,避免重复开发。


爱奇艺号 API 生成平台实践

爱奇艺号 API 生成平台,是一个低代码平台。由于爱奇艺号的技术栈主要基于 Java,所以使用的是 GraphQL 的 Java 实现。基于 graphql-java,API 生成平台主要做了以下功能优化及增强。


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

(2)动态接入监控:动态生成的 API,与其他普通接口一样支持 Prometheus 监控,保证监控的灵活性和服务的稳定性。

(3)灵活配置:可以动态生成 GraphQL 的 schema,方便后端接入新服务。

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


接下来将对以上功能进行详细介绍:

1.支持 Rest API

graphql-java 通过 Spring 的封装,位于整个架构的网关层或 BFF 层。项目 user-info-graphQL 依赖 graphql-java-spring,支持 Rest API 请求。平台的整体架构图如图 3-1 所示:



图 3-1


User-info-graphQL 的服务流程图如图 3-2 所示。客户端通过 graphql/前缀的 Rest API 方式请求,后端通过前缀与 GraphQL Query 绑定,从 DB 获取映射关系,最终转换成 GraphQL 支持的查询语法。


图 3-2

2.动态接入监控

在 user-info-graphQL 项目中,原本是通过 template url 来匹配任意自定义 url;导致监控平台只能显示 template url 的请求信息,如图 3-3 所示。这个问题可以通过重写 spring-boot-actuator 中获取 tags 的方法,将真实的 url 请求信息暴露到 Spring boot 的/actuator/prometheus 端点这个方法来解决,如图 3-4 所示。

图 3-3



图 3-4


通过暴露的监控端点接入 Prometheus,实现对新生成的 API 进行实时动态监控,示例效果如图 3-5 所示:



图 3-5

3.灵活配置

为了方便后端快速接入新增微服务,达到支持 API 动态扩展目的。项目中通过 Velocity 定义 schema 模板,通过 Java 注解、反射机制动态生成 graphqls 模板文件,如图 3-6 所示:




图 3-6


图 3-6 中的 GraphQL schema 模板,支持通过用户 UID 查询用户信息。用户信息是由多个微服务聚合而成,采用异步调用多个微服务并行获取数据。基于此模板,用户只需要实现 SPI 定义好的接口,就能实现对新增微服务的支持。


4.可视化 API 管理平台 

通过 API 生成管理平台,开发人员可以实现 API 接口的可视化配置、生成、动态监控等功能,达到开箱即用的效果,极大提升开发和运维效率


总结

通过 GraphQL 动态构建 BFF 服务层 API,聚合不同的微服务,相比于 Rest API 方式,能够减少后端重复开发,加快响应前端需求。后端开发人员只需要开发维护新增微服务,并通过 SPI 方式,增加 BFF 层对新增微服务的支持即可。


价值:

通过在爱奇艺号后端微服务引入 GraphQL 构建 BFF 服务层,可以达成以下效果:


开发方面的优势

  • 提升开发效率:后端开发人员职责分工明确,微服务与 BFF 层独立开发及维护。新增微服务接入方便,因 BFF 层对外的 API 支持动态生成,所以无需更改 BFF 层的代码,只需集中维护微服务。前端可以通过 GraphQL 的 schema 查看接口返回数据,减少前后端沟通成本。

  • 形成低代码平台:随着构建的微服务基础措施足够完善,BFF 层支持动态生成 API 接口,极大减轻重复工作量。


运行维护时的优势

  • 便于监控:新增 BFF 层 API 接口,通过支持 Prometheus 端点监控,无开发成本。

  • 支持系统高吞吐量:BFF 服务、微服务都是基于 docker 部署,支持 QPS 动态扩容,能够支持高并发。

  • 便于维护和扩展:基于 GraphQL 构建的 BFF 层,API 接口动态生成,层次清晰,更易维护、扩展。


难点:

  • 动态扩展查询支持,目前 schema 的定义都是基于明确字段的情况下,如果需要支持动态的查询支持,需要支持动态 schema 扩展和解析。

  • 中文文档少,Facebook 官方只发布了 JS 实现,Java 实现都是基于开源社区,文档和功能都不是很完善。


未来规划:

随着 BFF 端对 API 请求的多样化,需要动态支持新方法扩展及监控。目前 API 与请求的映射关系持久化在 MySQL 中,需要支持集群和高性能,后续逐步迁移到 ZK 或 Redis 中,并缓存到本地。


随着云原生和 K8s 的兴起,基于 K8s 部署的 Go 服务,更易扩容和维护。基于 Java 实现的 GraphQL,如果迁移到 K8s 上部署,很难实现快速扩缩容的效果。而 graphql-go 在 github 上的 star 高达 7k,可见热度极高。如果基于 Go 实现 BFF 端,API 与请求的映射关系可以存储于 K8s 的 Pod 配置文件中,并且通过一个 API 部署一类 Pod,进行服务隔离,可以更高程度的保证服务稳定。


本文转载自:爱奇艺技术产品团队(ID:iQIYI-TP)

原文链接:减少重复开发,GraphQL在低代码平台如何落地?


2021-02-02 07:003329

评论

发布
暂无评论
发现更多内容

找准风口,如何从运维转向 DevOps?

SoFlu软件机器人

软件测试 | 测试开发 | 想测试入门就必须要懂的软件开发流程

测吧(北京)科技有限公司

测试

Netty高并发处理架构设计介绍

孙大卫

架构 Netty 开发框架 9月月更

「工作小记」多个批量操作的链式实现

叶一一

前端 设计思维 React Hooks 9月月更

主流定时任务解决方案全横评

阿里巴巴云原生

阿里云 Serverless 云原生

软件测试 | 测试开发 | 一文带你了解K8S 容器编排(上)

测吧(北京)科技有限公司

测试

小六六学Netty系列之Java NIO(二)

自然

Netty 网络 9月月更

小六六学Netty系列之Java 零拷贝

自然

Netty 网络 9月月更

i++需要多少QPS才能测出BUG

FunTester

C语言_2 变量

泾箐

c 9月月更

SAP UI5 ManagedObject 的 Association 讲解

Jerry Wang

JavaScript typescript SAP UI5 ui5 9月月更

中文稀疏GPT大模型落地——通往低成本&高性能多任务通用自然语言理解的关键里程碑

阿里云大数据AI技术

自然语言处理 多任务 企业号九月金秋榜 GPT

软件测试 | 测试开发 | Jenkins 踩坑(三)| Email 配置与任务邮件发送

测吧(北京)科技有限公司

测试

云游戏产业链深度解析

Finovy Cloud

云计算 5G 云渲染 云游戏

Spring源码分析(九)lazy-init 在Spring中是怎么控制加载的

石臻臻的杂货铺

spring 9月月更

TOP 5!望繁信科技获评WAIC2022全球创新项目路演优胜项目

望繁信科技

WAIC2022

行业案例|长安汽车质量管理数据分析实践

Kyligence

质量管理 数据管理 长安汽车

软件测试 | 测试开发 | 数据持久化技术(Java)

测吧(北京)科技有限公司

测试

易周金融分析 | 多家银行试水特色网点揽客;自动驾驶颠覆传统车险模式

易观分析

自动驾驶 金融 银行 网点

C语言_3 选择结构

泾箐

c 9月月更

阿里云弹性计算技术专家樊毅伟:云上成本优化实践

阿里云弹性计算

自动化运维 资源利用

数据治理的内核:数据标准

Taylor

数据治理 大数据平台 数据管理平台 数据标准 大数据仓库

OpenHarmony中的HDF单链表及其迭代器

OpenHarmony开发者

Open Harmony

软件测试 | 测试开发 | 如何模拟真实使用场景?mock 技术来帮你

测吧(北京)科技有限公司

测试

蒙特卡洛方法与蒙特卡洛搜索树(一)

Joshua

机器学习 算法 蒙特卡洛

「趣学前端」骨架屏,分享一波前端UI组件开发的经验

叶一一

JavaScript 前端 组件 9月月更

长沙!《学习的学问》长沙分享会

博文视点Broadview

小六六学Netty系列之Netty群聊

自然

Netty 网络 9月月更

源于加速,不止加速-阿里云加速引擎的10年演化之路

阿里云视频云

CDN CDN加速 CDN技术

FreeRTOS记录(二、FreeRTOS任务API认识和源码简析)

矜辰所致

源码分析 FreeRTOS 9月月更 任务API

微信Windows端IM消息数据库的优化实践:查询慢、体积大、文件损坏等

JackJiang

sqlite 微信 网络编程 即时通讯 IM

减少重复开发,GraphQL在低代码平台如何落地?_架构_爱奇艺技术产品团队_InfoQ精选文章