实施GraphQL后端-前端的步骤指南
几乎所有的现代应用程序都使用REST APIs进行客户-服务器通信。然而,一旦一个应用程序随着新的需求扩展,最终会因为开发的反模式而大大降低应用程序的速度。
本文将探讨Backend-For-Frontend模式,以及开发者如何使用GraphQL实现这一模式,以消除传统REST API的负面因素。
后台为前台(BFF)模式
当API过度获取数据时: 客户端应用程序必须处理数据以创建页面所需的响应。
当API获取数据不足时: 客户端应用程序必须向RESP API执行额外的HTTP请求以检索所需的数据。
这最终会导致客户端和服务器之间出现一种被称为 "聊天式I/O "的开发反模式,并会大大降低应用程序的速度。
后端-前端 "是放置在客户端和API之间的数据转换层,以避免过度获取和获取不足,并消除反模式的聊天式I/O开发。
图1:说明一个使用BFF实现的应用程序
图1展示了一个使用Backend-For-Frontend模式实现的应用程序的简单设计图。在这个图中,我们可以观察到以下的请求/响应循环。
- 客户端向BFF发送了一个请求。
- 然后,Backend-For-Frontend与内部服务进行通信并收集所需的数据。
- 然后,它将数据聚合成客户端所需的形状。
- 它将成型的数据返回给客户端。
客户端通过采用这种方法与BFF进行交互,并且只接收填充页面所需的数据(没有更多或更少)。此外,随着客户端数量的增加,可以为每个客户端实现BFF,以检索适合其使用情况的数据。
因此,使用BFF可以通过简化的响应创建更快的页面加载,并消除客户端的额外网络调用,最终改善应用程序的用户体验。
为什么GraphQL是BFF的首选技术?
GraphQL是一种用于API的查询语言,也是一种用于用现有应用数据进行充分查询的运行时间。
GraphQL允许你用通俗的语言将数据从服务器有效地加载到客户端。
GraphQL API与REST API的不同之处在于,GraphQL允许客户定义响应的形状,与REST API不同(服务器决定响应形状)。
因此,GraphQL有助于创建高效的查询,客户可以指定在用户界面上显示内容所需的数据,这样数据就不会被过度取用和取用不足。这种情况有助于避免Chatty I/O,更重要的是,客户只需用一个端点(通过编写不同的查询)与后台沟通。
使用GraphQL构建一个BFF
现在我们已经理解了什么是前台后台,以及为什么要用GraphQL来实现它,让我们看看用GraphQL实现BFF。
你可以在任何编程语言中实现GraphQL,但我将使用Node.js来实现GraphQL API,在这个演示中管理一个用户集合。
第1步:先决条件
在继续之前,确保你已经在你的电脑上安装了Node.js和NPM。
为了确认安装,运行以下命令。
node -v
第2步:安装所需的库
首先,通过运行npm init命令创建一个新的Node.js项目。它将生成一个新的package.json。
我们将用Express网络服务器实现GraphQL。因此,我们需要三个包:
- GraphQL
- Express
- Express-GraphQL
运行下面的命令来安装下面给出的包。
npm install express express-graphql graphql
第3步:添加样本数据
之后,API需要一个数据源来获取请求的数据。如下图所示,我将模仿一个数据源,在 "data "目录下的一个名为 "users.js "的文件中添加一个样本数据列表,供本攻略参考。
// sample data structure in data/users.js
第4步:声明模式
之后,必须要定义GraphQL模式。GraphQL模式提供了一个客户端可以从API请求的数据形状。此外,它允许你声明用户可以用来读/写数据的查询和突变。
首先,我们必须创建一个GraphQL类型(Entity)来定义API中的用户。然后,创建一个名为 types 的新目录,并在该目录中创建一个名为 users.js 的文件。之后,打开该文件并添加以下代码。
const { GraphQLObjectType, GraphQLString, GraphQLInt } = require('graphql');
上面显示的实体提供了一个类型声明,并定义了模拟数据源中存在的用户的可用属性。
在声明了用户实体后,我们可以为我们的API定义业务逻辑函数。为了添加业务逻辑函数,创建一个名为 "resolvers "的新目录,并创建一个名为 "user-resolver.js "的新文件,然后添加如下所示的代码:
const users = require('../data/users');
上面显示的业务函数访问模拟数据源并执行样本查询。我们可以使用这些函数作为GraphQL查询的解析器。
成功添加业务函数后,我们现在可以定义消耗这些函数的GraphQL查询。创建一个名为 "schemas "的新目录,并在该目录内放置一个名为 "schema.js "的新文件。在新创建的文件中添加以下代码:
const { GraphQLObjectType, GraphQLString, GraphQLSchema, GraphQLList } = require('graphql');
上面显示的片段为GraphQL API创建了模式。对象 "RootQueries "定义了调用所定义的业务函数的可用查询(在解析回调中)。
对象 "schema "用可用的查询、类型和突变(如果有的话)创建GraphQL模式。这个模式在调用GraphQL API为客户端请求提供服务时被使用。
在定义这些模式时需要注意的一点是,我们使用了单独的文件来管理查询和类型。你可以在一个文件中定义所有的东西,但这是不可维护的,因为随着你的应用程序的扩展,这最终会产生难以阅读的代码。因此,我们为类型和查询创建了两个独立的文件,使代码更易读。
第5步:构建GraphQL API (BFF)
在声明了模式之后,我们可以用Express构建GraphQL API。在根目录下创建一个名为 "index.js "的文件,并添加如下所示的代码:
const express = require('express');
上面的片段成功地在"/graph "端点上配置了GraphQL API,并使用了前面定义的模式。
为了启动API,运行node index.js。之后,访问http:localhost:4000/graph来查看 GraphQL Playground。
观察行动中的BFF
一旦API启动,我们的Backend-For-Frontend就完成了有了GraphQL,我们现在可以执行查询以获得用户信息,并完全控制我们所检索的数据。通过这样做,不同的客户端可以只获得每个客户端需要的数据来填充用户界面,从而消除了过度获取。
例如,我们可以使用单一的端点(localhost:4000/graph)来为两个具有不同数据形状的客户端(Web/Mobile)查询数据。
这个过程详述如下,第一个片段为网络客户端获取四个变量(姓名、电子邮件、年龄、身份)。另一方面,第二个片段只为移动客户端获取两个变量(姓名和电子邮件)。
此外,GraphQL允许你对多个查询进行分组。因此,如果你的应用程序必须在一个页面上显示两组数据,你可以使用一个HTTP请求来获取两组数据,从而提高加载时间和性能。
这就是我们如何使用GraphQL来实现Backend-For-Frontend模式。这个API允许多个客户端使用单一的端点,并通过指定他们所需的内容来获取数据。
构建可组合的Web应用
不要建立网络单体。使用 比特来创建和组成解耦的软件组件--在你喜欢的框架中,如React或Node。构建可扩展和模块化的应用程序,提供强大和愉快的开发体验。
把你的团队带到 比特云来托管并共同协作开发组件,并作为一个团队加快、扩大和规范开发。尝试用设计系统 或微前端的可组合前端,或探索用服务器端组件的可组合后端。
在这篇文章中,我探讨了Backend-For-Frontends(BFF)的介绍,以及GraphQL如何帮助建立一个BFF的演练。
本文中实现的示例应用程序可以在我的GitHub仓库中访问。
我希望你觉得这篇文章对你有帮助。
谢谢你的阅读。