最近几年,微服务架构在Web开发领域受到越来越多的追捧。但是,微服务架构中有一个非常头痛的问题:不同服务之间的数据通信问题。不同的微服务之间通信的方式有很多种,但大多数情况下,我们使用RESTful API来进行通信。RESTful API是一种简单易用的通信方式,但是它的缺点也很明显:API 接口较多时维护成本高、数据冗余及性能问题等。而 GraphQL,因其具有高度灵活性,强大的查询能力和节约流量的特点,正逐渐成为微服务架构中数据通信的首选方案。本文将介绍在微服务架构中使用 GraphQL 进行数据通信的技术实践。
什么是 GraphQL
GraphQL 是一种由Facebook开发的数据查询语言和运行时。GraphQL 构建于类型系统之上,并允许客户端根据需要声明需要查询的数据,并在单个请求中进行多个查询。GraphQL 还允许开发人员通过定义自己的类型和关系来扩展现有数据模型。
使用GraphQL,客户端可以精确地声明它需要哪些数据,并获得提供单个请求所需数据的响应。这意味着可以避免在传统 RESTful APIs 中常见的“过度拉取”的问题(即获取比所需数据更多的数据)。
GraphQL 提供了以下优点:
灵活性:GraphQL 允许你描述你的数据模型,包括类型属性。客户端可以通过声明需要的属性来查询任何级别的数据支持。这种灵活性使得 GraphQL 非常适合微服务架构中的数据通信。
节省网络带宽:在单个 GraphQL 请求中执行多个查询,而不是多个 RESTful API 请求。这大大降低了网络的负担,尤其是当网络性能受到限制的时候。
避免“过度拉取”:传统 RESTful API 接口通常返回大量的数据,其中大部分对于客户端来说都不需要。GraphQL 允许开发者精确地声明需要哪些数据,并且只返回所需数据。
微服务和 GraphQL
微服务架构有很多优势,也有很多挑战。其中一个重要的问题是服务之间的数据通信问题。RESTful API 是一种使客户端和 Web 服务进行通信的常见方式。对于单个服务而言,这个方案可能是不错的。但在微服务架构中,如果每个服务都有自己的RESTful API,那么就会出现大量的API接口,我们需要在这些接口间花费大量的时间和精力,同时还会产生代码冗余、维护成本高等问题。
此时,GraphQL 作为新的数据通信协议,可以解决上述问题。相较于 RESTful API,GraphQL 有以下优点:
- 可自动化生成GraphQL API,减少API的维护成本
- 更精细的权限控制
- 更高效的数据传输协议
GraphQL 和微服务的整合
在将 GraphQL 应用于微服务架构之前,我们需要明确几个概念:服务端,数据源和客户端。在微服务中,每个服务都有一个服务端、数据源(通常是数据库)和一个或多个客户端,而GraphQL通常被用于服务端和客户端之间的数据通信。下面是将 GraphQL 应用于微服务架构的步骤:
第一步:为服务定义 GraphQL API
为给定服务创建 GraphQL API是第一步。这可以通过 a GraphQL schema 描述服务的数据模型来完成。为了使用GraphQL,服务应该实现 GraphQL 的数据查询语言,并能以 GraphQL schema 的形式定义服务数据模型的结构。
例如,让我们考虑一个由两个微服务组成的医院管理应用程序。其中一个服务提供患者信息,另一个服务提供医生信息。我们可以使用 GraphQL 为每个服务创建 schema,如下所示:
patientService
-- -------------------- ---- ------- ---- ------- - --- --- ----- ------- ---- ---- - ---- ----- - --------- ---------- ----------- ----- ------- -
doctorService
-- -------------------- ---- ------- ---- ------ - --- --- ----- ------- ---------- ------- - ---- ----- - -------- --------- ---------- ----- ------ -
第二步:在服务端实现 GraphQL API
为了实现 GraphQL API,我们需要一个 GraphQL Server。GraphQL的生态中,有很多常用的GraphQL的服务实现,例如 Apollo、Prisma等。在我们的医院管理应用程序中,我们可以使用Apollo GraphQL server作为我们的GraphQL server实现,如下所示:
-- -------------------- ---- ------- -- ------------------------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- ---- - ----- -------- -------------- ----- -------- - ---- ---- ------- - --- --- ----- ------- ---- ---- - ---- ----- - --------- ----------- ----------- ----- ------- - -- -------- --------- -- -------- ------- ---- ---- -------- ----- --------- - - ------ - --------- ----- -- -- - ----- -------- - ----- ------------ ------ --------- -- -------- ----- ------ ----- -- - ----- ------- - ----- ------------ ---- ----------------- --- ------ -------- - - - -------- ------ ----- ------ - --- -------------- --------- ---------- --- ----- --- - ---------- ------------------------ ---- ----- ---------- -- ------------ ---- -- -- -- --------------- ------ ----- -- ----------------------------------------------- --
请注意,我们在这里定义了一个GraphQL schema,绑定了数据库中Patient的查询操作。在请求 '/graphql' 路径时会触发一个GraphQL查询请求,并在patients
中返回所有患者数据和patient(id:ID!)
中按照ID返回单个患者数据。
第三步:将 GraphQL API 集成到客户端
最后,我们需要在客户端中使用 GraphQL API。我们可以使用各种语言和框架来实现客户端。在这个例子中,我们使用 React 作为我们的客户端,并使用 Apollo-Client 作为我们的 API 客户端,如下所示:
-- -------------------- ---- ------- -- ------------------------- ------ ----- ---- -------- ------ -------- ---- ------------ ------ --- ---- -------- ------ - -------------- - ---- ----------------- ------ - ------------- ------------- - ---- ----------------- ------ - -------------- - ---- ----------------- ------ - ---------- - ---- ------------------------------ ----- -------- - ---------------- ---- -------------------------------- --- ----- -------- - -------------- - ------- -- -- - ----- ----- - ------------------------------ ------ - -------- - ----------- -------------- ----- - ------- --------- - --- - - --- ----- ------ - --- -------------- ----- -------------------------- ------ --- --------------- --- ---------------- ------------------ --------------- ---------------- ---- -- ----------------- -------------------- ------------------------------- -- ------------- ------ ----- ---- -------- ------ - --------- --- - ---- ----------------- ----- -------------- - ---- ----- - -------- - -- ---- --- - - -- -------- ------------- - ----- - -------- ------ ---- - - ------------------------- -- --------- ------ ------------- -- ------- ------ ------- ------------------ ------ - ---- -------------------------- -- - --- ----------------- ----------------------- -------------------- ----- --- ----- -- - ------ ------- ------------
在这个例子中,我们通过查询Patient服务中的所有患者的API将患者的列表显示出来,并使用gql
模板标记定义GraphQL查询,如下所示:
-- -------------------- ---- ------- ----- -------------- - ---- ----- - -------- - -- ---- --- - - --
最后我们将PATIENTS_QUERY查询加载到组件中:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - --------- --- - ---- ----------------- ----- -------------- - ---- ----- - -------- - -- ---- --- - - -- -------- ------------- - ----- - -------- ------ ---- - - ------------------------- -- --------- ------ ------------- -- ------- ------ ------- ------------------ ------ - ---- -------------------------- -- - --- ----------------- ----------------------- -------------------- ----- --- ----- -- - ------ ------- ------------
此处的PatientList
组件首先会向 patientService-GraphQL 服务请求获取所需的患者数据,然后使用返回的数据来渲染页面。
结论
在微服务架构中使用 GraphQL 进行数据通信的优势显而易见:灵活性、节省网络带宽和避免“过度拉取”,都可以改善微服务架构的数据通信问题。在实际应用过程中,我们可以选择不同的 GraphQL Server 或 GraphQL Client 来搭建应用。例如,我们可以使用Apollo-Server作为我们的GraphQL Server实现,使用 Apollo-Client 作为我们的API客户端实现,从而在微服务架构中实现更高效、更精细的数据传输。对于那些希望减少API维护成本、保证数据安全性和提高应用程序性能的开发人员,使用 GraphQL 是一种非常好的选择。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672a2faaddd3a70eb6cf6514