GraphQL Server 的 API 设计规范及最佳实践

面试官:小伙子,你的数组去重方式惊艳到我了

前言

GraphQL 在前端开发中越来越受欢迎,很多公司和团队都开始采用 GraphQL 构建他们的服务端 API。然而,GraphQL 的灵活性与强大性也带来了许多挑战和需要注意的地方。本文将介绍一些 GraphQL 服务器端 API 设计的规范和最佳实践,帮助您设计出更好的 GraphQL API。

设计规范

1. 定义好 Schema

GraphQL 的核心是 Schema。Schema 定义了数据类型、字段以及它们之间的关系。因此,在设计一个 GraphQL API 时,首要任务就是定义好 Schema。

Schema 可以被定义为一个字符串或写成一个类。如果你使用的是 Apollo Server,则可以考虑写成一个类。一个好的 Schema 应该包含以下几个部分:

  • Query:查询数据(必需)
  • Mutation:修改数据(可选)
  • Subscription:实时数据更新(可选)

比如,下面是一个简单的电影 Schema:

---- ----- -
  --- ---
  ------ -------
  --------- -------
  ------- ---------
-

---- ------ -
  --- ---
  ----- -------
-

---- ----- -
  ------- --------
  --------- ----- ------
-

---- -------- -
  --------------- -------- ----------- ---- --------- ------ ------
  --------------- ---- ------ -------- ----------- ---- --------- ------ ------
  --------------- ----- --
-

2. 使用 DataLoader 来优化数据加载

在 GraphQL 中,一个查询中通常会包含多个嵌套的字段,这意味着多次从数据库中读取数据,将会对性能产生较大的影响。

为了解决这个问题,我们可以使用 DataLoader,它可以缓存请求,然后批量处理数据。这样,我们就可以在一个请求中获取所有数据,而不需要多次查询数据库。

比如,假设我们有一个查询返回所有电影及电影演员的姓名:

-
  ------ -
    --
    -----
    ------ -
      ----
    -
  -
-

如果没有 DataLoader,GraphQL 服务器会为每个电影和演员姓名分别从数据库开始查询。但是,如果启用 DataLoader,请求将会被缓存并批量处理,从而获得更好的性能。

3. 使用 Context 传递环境信息

在 GraphQL 中,Context 对象在整个查询过程中被传递,并许多库都会支持在 Context 中存储会话、用户授权信息等相关信息。

使用 Context 可以使得在 Resolver 函数之间传递状态信息变得更加容易。

比如,我们可以将用户认证信息,在 Resolver 中通过 Context 传递给查询、修改、删除函数:

----- -------- ---------------- - -- -- - ---- -- -
  ----- ----- - ----- -------------------

  -- ----- -- ---------------------- -
    ------ ------
  - ---- -
    ----- --- ----------------------
  -
-

----- --------- - -
  ------ -
    ------ -------------
  --
  --------- -
    --------- -------- ----- - ---- -- -- -
      -- ------- -
        ----- --- ----------------------
      -
      ------ ------------------
    --
    ------------ -------- ----- - ---- -- -- -
      -- ------- -
        ----- --- ----------------------
      -
      ------ ------------------
    --
    ------------ -------- ----- - ---- -- -- -
      -- ------- -
        ----- --- ----------------------
      -
      ------ ------------------
    -
  -
--

4. 参数验证

GraphQL 请求可以包含很多参数,如果没有良好的参数验证机制,则有可能导致不良后果,比如 SQL 注入攻击。

为了避免这种情况,我们需要在 GraphQL 服务器上实施参数验证,可以使用一些现有的库,例如 Joi 或 Yup。

下面是一个使用 Joi 进行参数验证的例子:

----- --- - ---------------------

----- ----------- - ------------
  ------ ------------------------
  ----------- ----------------------------------
  --------- ----------------------------------------------------
---

----- --------- - -
  --------- -
    --------- -------- ----- -- -
      ----- - ----- - - ---------------------------
      -- ------- -
        ----- --- ---------------------
      -
      ------ ------------------
    -
  -
--

最佳实践

1. 分层结构

对于大型的 GraphQL API,我们应该考虑将业务逻辑与数据层分离,这样可以使代码更具可读性和可维护性。

我们可以将 Resolver 的实现放在独立的服务中,并使用 Repository 模式来处理数据操作。这样可以将 Resolver 与数据访问分离,更容易进行单元测试、集成测试等。

--- ---
  --- ----------
    --- ------------------
  --- -------
    --- ---------------
  --- -----
    --- ------------
  --- ------------
  --- ---------

2. 使用 Dataloader 和 Batch

在处理关系型数据时,批量获取数据和使用 DataLoader 可以极大提高 GraphQL API 的性能。

在 Apollo Server 中使用 DataLoader 很简单。我们只需要定义一个数据加载器,然后在 Resolver 函数中使用。

----- ---------- - ----------------------

----- ----------- - --- ---------------- -- -
  ------ ----------------------
---

----- --------- - -
  ------ -
    ------ --- - -- -- -- -
      ------ --------------------
    -
  -
--

Batching 也是提高性能的另一种方式。Batching 允许多个请求在一个请求中处理,这样就可以避免重复查询。

3. 利用 Fragment 提高查询可读性

在 GraphQL 中,查询通常包含嵌套的字段,这会导致查询变得冗长且难以理解。为了优化查询的可读性,我们可以使用 Fragment。

Fragment 允许我们定义一个可复用的字段集合,然后将其应用到查询中。

-------- ----------- -- ----- -
  ----
  ---
-

----- -
  --------- -- -
    -----
    -------- -
      ----
      ---
    -
    ------ -
      --------------
    -
  -
-

在这个例子中,actorFields 可以在我们的查询中被多次使用,使我们的查询代码更加简洁和易于理解。

4. 明确错误信息

GraphQL 返回的错误信息可能不够明确或不够详细,这可能会使开发更加困难。

为了提高 GraphQL 的错误信息质量,我们可以捕获并以标准的格式返回错误信息。GraphQL 提供了一个标准的错误结构,其中包含了错误信息、位置和路径。

-
  --------- -
    -
      ---------- ---------------
      ------------ -
        -
          ------- --
          --------- -
        -
      --
      ------- -
        -------
      -
    -
  --
  ------- -
    -------- ----
  -
-

5. 启用缓存

GraphQL 是一种更强大的查询语言,可以提高服务器和客户端的性能。但是,它也会带来一些挑战,例如在重复查询时需要消耗更多的计算资源。

为了避免这个问题,我们可以启用缓存。GraphQL API 的缓存可以提高性能并减少服务器的负载。

我们可以使用一些现有的缓存库,比如 Redis,或者使用一些各种云提供商所提供的缓存服务。

结论

GraphQL 作为一种新兴的技术,已经在很多公司和团队中被广泛使用。在本文中,我们介绍了一些 GraphQL 服务器端 API 设计的规范和最佳实践,并希望它可以帮助您更好地设计出高效和易用的 GraphQL API。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/6700d846c842884a45a8df06


猜你喜欢

  • CSS Reset 使用中常见的坑及解决方法

    在开发网页时,我们经常会使用 CSS Reset 来消除浏览器默认样式,以避免不同浏览器之间的布局差异。然而,CSS Reset 在实际使用过程中,会遇到一些常见问题,本文将深入剖析这些问题,并给出解...

    15 天前
  • 解决 JavaScript 模块化开发中常常遇到的问题

    前言 在前端开发中,模块化开发是一个重要的话题。随着项目的复杂度不断增加,我们往往需要将代码分割成多个模块进行开发和维护。而在这个过程中,我们也会遇到一些常见的问题。

    15 天前
  • 前端技术:在 Redux 中使用 setState 和上下文 API 的区别

    React 和 Redux 是现代 Web 开发的主要技术之一,它们是构建 Web 应用程序的强大工具。在使用 React 和 Redux 进行开发时会遇到一些常见问题,比如在 Redux 中使用 s...

    15 天前
  • ECMAScript 2019:理解如何在 React 应用程序中使用 Hooks

    随着前端技术的不断发展,React 成为了当下最流行的前端框架之一。React 使用组件化的思想,将界面拆分成一系列组件,每个组件封装了自己的状态和行为。在 React 的早期版本中,我们需要使用类组...

    15 天前
  • 如何使用 ES6 改善网站的用户交互体验

    现代 Web 应用要求更快、更流畅且更快地响应用户操作。在传统的 AJAX 等技术的基础上,ES6 的一些新特性为前端开发带来了更多便捷和灵活性,进而改善用户交互体验。

    15 天前
  • Promise 和原生的 XMLHttpRequest 相结合请求数据

    Promise 和原生的 XMLHttpRequest 相结合请求数据 前言 在开发前端应用时,经常需要向后端请求数据以获取特定功能所需的数据。在现代的前端开发中,Ajax 已经成为了一个必备的技术。

    15 天前
  • TypeScript 中使用 Sequelize ORM 的教程及注意事项

    引言 随着 Web 应用的日益复杂,前端开发变得越来越重要。TypeScript 是一个类型化的 JavaScript 语言,它为前端开发人员提供了更好的代码调试、维护以及协作的体验。

    15 天前
  • MongoDB 如何处理 BSON 格式数据?

    MongoDB 是一个流行的 NoSQL 数据库,它使用了 BSON(Binary JSON)格式来表示数据。BSON 是一种轻量且快速的二进制序列化格式,旨在提供比 JSON 更高的效率和更好的可扩...

    15 天前
  • ES12 中的 globalThis: 解决跨平台对象调用问题的解决方案

    在前端开发领域中,有时候需要在不同平台之间进行对象调用,但由于不同平台对于全局变量的实现方式不同,可能会导致对象无法正确调用。为了解决这个问题,ES12 新增了一个全局对象 globalThis。

    15 天前
  • Tailwind CSS 中如何调整组件的大小和间距

    简介 Tailwind CSS 是一个基于类名的 CSS 框架,它提供了大量的预定义类,可以帮助我们快速构建 UI 组件。但是,这些组件的大小和间距不一定符合我们的要求,因此本文将介绍如何在 Tail...

    15 天前
  • React 组件测试:使用 Enzyme 和 Sinon 来测试

    React 是一个广泛使用的 JavaScript 库,用于在 Web 上构建用户界面。在开发 React 应用程序时,我们需要确保代码具有高质量和可靠性,并且能够使用灵活的测试框架来测试组件。

    15 天前
  • 在 Mocha 测试中正确处理 Express 的中间件

    在 Mocha 测试中正确处理 Express 的中间件 Express 是一个常用的 Node.js Web 应用框架,提供了非常丰富的中间件支持,可以快速构建起一个 Web 服务器。

    15 天前
  • 在 Custom Elements 中使用 JavaScript 的 Proxy 对象

    Web Components 是一种可以在 Web 上创建可重用的独立自定义元素的技术标准。Custom Elements 是 Web 标准团队提供的 API 之一,可以使开发人员创建自定义元素。

    15 天前
  • 如何在 Fastify 中使用 NATS 消息队列

    消息队列是一种广泛使用的异步通信的方式。它有助于构建高度可伸缩和可靠的应用程序,特别是在分布式系统中。NATS 是一种轻量级和高效的消息系统,它具有可伸缩性和高性能。

    15 天前
  • ES9 新增特性 SharedArrayBuffer 详解

    JavaScript 是一门在浏览器、服务器、移动设备以及其他场景应用广泛的编程语言,随着各种应用场景的不断增多,JavaScript 的性能也成为了大家关注的焦点。

    15 天前
  • 在使用 Chai 进行测试时如何指定测试用例的顺序?

    前言 在进行前端单元测试时,我们需要使用测试框架和断言库,而 Chai 是一个流行的断言库,它提供了丰富的断言方法和易于使用的 API 接口。在编写测试用例时,我们可能需要控制测试用例的执行顺序,本文...

    15 天前
  • 在 React SPA 应用中实现分页功能的技巧

    对于拥有大量数据列表的单页应用程序(SPA)来说,实现分页功能是至关重要的。在本文中,我们将介绍如何使用 React 实现分页功能,并提供相应的示例代码。 实现分页功能的前置条件 在实现分页功能之前,...

    15 天前
  • 开始使用无障碍技术让自己的 WordPress 网站更易访问

    无障碍技术是指让所有人都能同等地使用网站、应用程序和其他数字产品的技术,这包括身体残疾人、认知障碍者、老年人等。对于前端开发来说,创建一个易于访问的 WordPress 网站是至关重要的。

    15 天前
  • 在 Jest 中维护动态导入的 Web

    本文介绍如何在 Jest 中维护动态导入的 Web,涉及到 Webpack、Babel、Jest 的使用和配置。动态导入是指在代码运行时才加载某些模块,这些模块通常是比较大、复杂、依赖较多的模块,而且...

    15 天前
  • 如何在 GraphQL 中处理图像数据

    在现代 Web 开发中,图像数据是不可避免的一部分。GraphQL 是一种查询语言,用于 API 的开发,它可以让我们更加灵活地处理数据。在本文中,我们将探讨如何在 GraphQL 中处理图像数据,包...

    15 天前

相关推荐

    暂无文章