GraphQL 是一个现代化的 API 交互协议,它有效地解决了 RESTful API 中遇到的一系列问题。在 GraphQL 中,前端可以灵活地获取所需要的数据,从而不必依赖于 API 的返回格式。本文将详细介绍 GraphQL 架构设计的实战技巧,并分享一些我们在实践中的经验。
GraphQL 基本结构
在 GraphQL 中,有三个基本概念:查询 (Query)、变异 (Mutation) 和订阅 (Subscription)。
- 查询:查询是获取数据的主要方式。前端可以指定查询中包含的数据,而后端则负责将所需数据返回给前端。一般情况下,查询返回的数据根据前端指定的需求进行过滤,这样前端就可以更快地获取所需数据。
- 变异:变异是用于修改数据的主要方式。前端可以指定用于修改的数据,而后端则负责将修改结果返回给前端。
- 订阅:订阅是允许前端实时获取后端数据更改的一种方式。
这些基本概念可以相互组合,以实现更加复杂的数据交互需求。
GraphQL 架构设计的技巧
在实践中,GraphQL 架构的设计可以采用以下一些技巧:
1. 合并查询
GraphQL 允许前端查询多个数据项。通常情况下,我们可以把多次独立查询合并成一次查询,从而减少查询的次数和网络负载,提高应用性能。
例如,下面的查询会向后端请求两个用户的姓名和头像 URL:
-- -------------------- ---- ------- - ------ -------- -- - ---- ------ - ------ -------- -- - ---- ------ - -
可以把这个查询合并成以下查询:
-- -------------------- ---- ------- - ------ -------- -- - ---- ------ - ------ -------- -- - ---- ------ - -
2. 使用分页查询
GraphQL 支持分页查询,因此可以根据需求返回指定的数据列表。这样可以使得前端代码更加简单,而后端也可以更加高效地返回大量数据。
例如,下面的查询会查询前 20 个用户:
{ users(count: 20) { id name avatar } }
3. 禁用不必要的查询字段
在查询的时候,可以禁用任何不必要的查询字段。这可以保证数据传输的最小化,并最终提高应用程序的性能。
例如,下面的查询会查询用户的 ID、姓名和头像 URL:
{ user(id: 1) { id name avatar } }
在禁用查询字段之后,下面的查询仅返回用户的 ID:
{ user(id: 1) { id } }
4. 使用片段
GraphQL 支持片段 (Fragment),允许我们将需要重复使用的查询字段进行抽象。这样可以避免在多次查询中重复添加查询字段。
例如,下面的查询查询出了多个音乐列表,每个列表中包含有音乐的 ID、音乐名称和歌手名称:
-- -------------------- ---- ------- - ---------- ------------ -- - ------ - -- ---- ------ - ---- - - - ---------- ------------ -- - ------ - -- ---- ------ - ---- - - - -
使用片段之后,可以简化这个查询,如下所示:
-- -------------------- ---- ------- - ---------- ------------ -- - ------ - -------------- - - ---------- ------------ -- - ------ - -------------- - - - -------- ----------- -- ----- - -- ---- ------ - ---- - -
5. 使用 DataLoader
DataLoader 是一个数据加载库,专门用来解决在 RESTful API 中遇到的前端性能问题。在 GraphQL 中,它可以使得后端更加高效地处理查询。
例如,下面的查询将查询出多个用户和他们的订单:
-- -------------------- ---- ------- - ------ -------- -- - -- ---- ------ - -- ------ - - ------ -------- -- - -- ---- ------ - -- ------ - - -
如果不使用 DataLoader 处理这个查询,会造成 N + 1 问题。使用 DataLoader 解决 N + 1 问题后,这个查询如下:
-- -------------------- ---- ------- - ------ -------- -- - -- ---- ------ - -- ------ - - ------ -------- -- - -- ---- ------ - -- ------ - - -
实现示例
下面是一个使用 GraphQL 架构设计的示例。在这个示例中,我们将使用 Node.js 环境和 Apollo Server 来实现 GraphQL 的服务端,同时使用 React 和 Apollo Client 实现前端对 GraphQL 的查询。
实现服务端
在 Node.js 环境中,我们首先需要安装以下软件来实现 GraphQL 服务端:
npm install graphql apollo-server-express express
然后,在 app.js 中添加以下代码来初始化 Apollo Server:
-- -------------------- ---- ------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- --- - ---------- ----- -------- - ---- ---- ----- - ------ ------------------- ----- -------- --- - -- ----- --------- - - ------ - ----------------- --- --- --- -- - - -- -- -- ----- ------ - --- -------------- --------- ---------- --- ------------------------ --- --- ------------ ----- ---- -- -- -- --------------- ------ ----- -- -------------------------------------------- --
实现客户端
在客户端中,我们需要安装 Apollo Client:
npm install apollo-boost react-apollo
然后,我们可以使用以下代码来使用 Apollo Client 查询服务端的计算乘积功能:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ -------- ---- ------------ ------ - --------------- ------------- --------- -------------- ---- --------- - ---- ----------------- ----- ------ - --- -------------- ----- --- ---------- ---- ------------------------------- --- ------ --- ---------------- --- ----- ----------- - ---- ----- -------------------- ----- --- ----- - ------------------- --- -- --- - -- -------- --------- - ----- - -------- ------ ---- - - --------------------- - ---------- - -- --- -- -- -- --- -- --------- ------ ------------------ -- ------- ------ -------- ------- ------ ----------- ---------------------------- - -------- ----- - ------ - --------------- ---------------- -------- -- ----------------- -- - -------------------- --- ---------------------------------
总结
本文主要介绍了 GraphQL 架构设计的实战技巧,并分享了一些在实践中的经验。使用 GraphQL 架构可以提高应用程序的性能,并且使得前后端协作更加紧密。当然,这只是介绍的冰山一角。在实践中,我们还需要根据实际情况进行具体的架构设计,以实现最优的数据交互方式。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64b3d18748841e989400cf47