GraphQL Schema 设计指南(下)

本文为 GraphQL Schema 设计指南的第二部分,前面的内容请参考GraphQL Schema 设计指南(上)。本文将继续深入讨论 GraphQL Schema 的设计原则和技巧,以及如何优化和维护 Schema。

1. 数据模型的设计

在设计 GraphQL Schema 之前,我们需要先对应用程序的数据模型进行建模。合理的数据模型是一个成功 GraphQL Schema 设计的必要条件。理想情况下,每个数据模型都应该对应一个 GraphQL 类型,这样就可以直接将数据库中的数据映射到 GraphQL 表示形式中。

数据模型的设计需要考虑以下几个因素:

  • 数据库的数据类型
  • 数据库的关系模型
  • 实体属性的关联关系

以下是一个简单的数据库模型示例(使用 MongoDB):

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

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

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

根据上述数据模型,我们可以设计出以下 GraphQL 类型:

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

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

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

2. 避免过多的嵌套类型

GraphQL 的优势之一是可以轻松地在查询中深度嵌套对象。然而,过多的嵌套可能会导致查询变得复杂和难以维护。

为了避免过多的嵌套,我们可以将某些嵌套类型提取出来,单独定义为 GraphQL 类型。例如,我们可以将 Comment 中的 authorpost 提取出来,单独定义为 CommentsAuthorCommentsPost 两个类型:

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

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

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

这样,我们在查询评论时就可以选择嵌套返回作者和博客文章的全部信息,也可以单独查询作者和博客文章的信息:

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

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

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

3. 利用 Union 和 Interface 类型提高 Schema 的灵活性

在 GraphQL Schema 中,我们可以使用 Union 和 Interface 类型实现多态性和灵活的查询。Union 和 Interface 类型可以让我们将不同类型的对象归为一类,提高代码的可读性和可维护性。

3.1 Union 类型

Union 类型可以将多个 GraphQL 类型组合成一个类型。例如,我们可以定义一个 SearchResult 类型,表示搜索返回的多个不同类型的结果:

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

当我们需要搜索时,只需要执行一个查询,同时获取多个不同类型的结果:

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

3.2 Interface 类型

Interface 类型可以定义一组字段和类型,作为一组类型的公共属性。例如,我们可以将 BlogPostUserComment 定义为 PostEntity 接口类型:

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

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

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

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

这样,我们就可以使用 PostEntity 接口类型获取所有 PostEntity 的共有属性,同时还可以针对每种类型进行进一步的查询:

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

4. 定义输入类型

GraphQL Schema 不仅可以定义输出类型,还可以定义输入类型。使用输入类型可以在查询和变更中重复使用参数,提高代码的可读性和可维护性。

例如,我们可以定义一个 CreateUserInput 输入类型,用于在 GraphQL 变更中创建新的用户:

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

然后,在定义 Mutation 类型时,我们可以使用 CreateUserInput 作为参数类型:

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

查询或变更时,可以将 CreateUserInput 作为参数传递:

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

5. 使用自定义标量类型

除了 GraphQL 的默认标量类型(例如 StringIntFloatBooleanID),我们还可以定义自己的标量类型,以适应特定的应用场景。

例如,我们可以定义一个 Date 标量类型,用于在 GraphQL Schema 中表示日期:

------ ----

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

在实现 Date 标量类型时,我们需要编写一个解析器函数,将输入转换为 JavaScript Date 类型。以下是一个 Date 标量类型的示例实现:

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

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

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

这样,在查询返回时,我们就可以将 createdAt 字段的类型设置为 Date 标量类型:

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

6. 将 Schema 按功能模块拆分

当 Schema 变得复杂时,我们可以将其拆分为多个功能模块,以管理代码并提高可读性和可维护性。例如,我们可以将所有与博客文章相关的查询和变更放在一个独立的子类型中:

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

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

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

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

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

这样,我们就可以根据业务逻辑的不同将 Schema 拆分为多个子类型,并使代码更易于管理和理解。

结论

本文介绍了 GraphQL Schema 设计的一些技巧和最佳实践。通过设计合理的数据模型、避免过多的嵌套类型、利用 Union 和 Interface 类型提高 Schema 的灵活性、定义输入类型、使用自定义标量类型和将 Schema 按功能模块拆分,可以让我们设计出易于维护和扩展的 GraphQL Schema。

最后,我们要认识到,Schema 设计并不是一次性完成的事情。随着应用程序的不断发展和变化,可能需要不断地调整和修改 Schema,以适应新的需求和变化。因此,谨慎地设计和维护 Schema 是实现高效 GraphQL API 的关键。

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


猜你喜欢

  • ES6 之 Promise(SE 读书笔记)

    Promise 是一个在 JavaScript 中很常用的异步编程解决方案,它可以帮助我们管理复杂的异步操作,让代码更加简洁和易于维护。本文将介绍 Promise 的基本用法、API 和一些常见应用场...

    10 天前
  • 使用 Headless CMS 构建云存储服务的技术架构设计

    前言 在现代化互联网应用中,云存储服务是一个非常重要的组件。它不仅可以为用户提供便利的存储服务,还能为应用提供高效且可靠的存储解决方案。而在这些服务中,Headless CMS 是一种非常流行的技术架...

    10 天前
  • 如何在 ECMAScript 2020 中使用 Promise.allSettled 处理所有 promise 的回调

    随着 JavaScript 编程语言的不断发展,Promise 成为了现代异步编程中不可或缺的工具之一。而 Promise.allSettled 按照它的名称,是用来处理所有 promise 的回调。

    10 天前
  • 利用 Enzyme 测试 React 组件的 DOM 节点

    Enzyme 是一个 React 组件测试库,它提供了一组工具来轻松地测试 React 组件和它们的 DOM 节点。这使得开发人员可以更加轻松地测试他们的组件,确保它们满足预期,而不需要手动操作 DO...

    10 天前
  • 如何解决 MongoDB 数据丢失的问题

    MongoDB 是一个流行的开源文档数据库,由于其灵活性和可扩展性而受到前端工程师的欢迎。但是,有时候您可能会遇到数据丢失的问题,这可能会导致不可逆转的业务损失。在这篇文章中,我们将探讨 MongoD...

    10 天前
  • PM2 进程启动异常的常见问题及解决方法

    在前端开发中,我们经常会使用 PM2 工具来管理 Node.js 服务器上的进程。但是,在实际使用过程中,我们经常会遇到一些进程启动异常的情况,如果不及时解决,可能会影响到服务的稳定性和可靠性。

    10 天前
  • 无障碍设计需要考虑什么?

    随着信息技术的发展以及网页互联网的普及,无障碍设计在前端开发中变得越来越重要。无障碍设计是指在设计产品或服务的过程中,考虑如何使所有人都能够平等地访问和使用这些产品或服务。

    10 天前
  • 了解样式规范化 Normalize.css 和 CSS Reset

    在网页开发过程中,每个浏览器都有自己的默认样式,不同浏览器之间的默认样式存在差异,这就给网页开发造成一定的问题。针对这个问题,前端界出现了 Normalize.css 和 CSS Reset 这两种样...

    10 天前
  • 在 ES8 中使用 Object.values() 方法快速查找对象中的属性值

    JavaScript 中的对象是一种数据结构,它由一组属性和值组成。我们可以使用不同的方式来读取对象中的属性值,其中一种方式就是使用 Object.values() 方法。

    10 天前
  • TypeScript 中的命名空间和模块

    前言 TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的一个超集,通过为 JavaScript 提供静态类型检查来提高代码的可维护性和可读性。

    10 天前
  • 什么是 Serverless 服务

    Serverless 服务是一种基于云计算的新型计算模型,它将应用程序的开发和运维过程中的服务器管理交给了云服务提供商,使开发者专注于业务逻辑的实现而不用关心服务器的维护、扩容以及备份等问题。

    10 天前
  • ES7 优化 Promise 的错误处理方法

    前言 Promise 是现代 JavaScript 中处理异步操作的重要工具,但在处理错误时,Promise 的行为有时会变得棘手和难以掌控。ES7 (2016) 引入了两个新的关键字 async 和...

    10 天前
  • Next.js:部署发布和常见错误解决方案

    作为一名前端开发人员,部署和发布网站是一个必须要掌握的技能。然而,很多人在部署过程中遇到了各种各样的问题,并且不知道如何解决。Next.js 是一个非常受欢迎的 React 框架,它为我们提供了快速开...

    10 天前
  • 如何使用 Hapi.js 和 Handlebars.js 构建动态 Web 应用程序?

    前端开发的重点是构建交互性更强的Web应用程序。而现代化的Web应用程序可能需要运用到各种技术。其中,Hapi.js 和 Handlebars.js 是每个前端工程师应该掌握的框架。

    10 天前
  • 如何使用 Fastify 框架构建 GraphQL API

    Fastify 是一个快速的 web 服务器框架,让构建高效的应用程序非常方便。GraphQL 是一种强大的查询语言,允许客户端指定需要获取的数据,而服务端只返回客户端请求的数据,减少了传输的数据量。

    10 天前
  • Headless CMS 如何实现完整性检查和数据验证

    什么是 Headless CMS Headless CMS 是内容管理系统的一种,它不同于传统的 CMS,传统 CMS 通常提供一个完整的解决方案,包括后端管理和前端展示,而 Headless CMS...

    10 天前
  • Tailwind CSS 教程之聚焦功能

    Tailwind CSS 是一款实用的 CSS 框架,它的显著特点是提供了一组与设计系统紧密集成的可复用 UI 组件和样式类。Tailwind 通过对样式类的精心设计,让开发者可以快速构建现代 Web...

    10 天前
  • 使用 Mocha 和 Protractor 进行 Angular 单元测试的步骤和技巧

    介绍 在开发 Angular 应用程序时,单元测试是非常重要的一环,它可以帮助您验证代码的正确性、提高代码的稳定性和可靠性。在本文中,我们将学习如何使用 Mocha 和 Protractor 进行 A...

    10 天前
  • Flexbox 概述:为什么它还不够完美?

    介绍 Flexbox是一种布局方式,它使得在不同的屏幕大小和设备之间,网站或者应用程序的布局变得相对容易自适应。在过去的几年中,前端开发人员积极地采用了Flexbox,并在实践中找到了许多解决方案,但...

    10 天前
  • MongoDB 数据库如何进行备份

    MongoDB 是一款高性能、可伸缩、非关系型数据库。对于运行重要业务的团队来说,数据备份至关重要。本文将介绍 MongoDB 数据库如何进行备份,并提供详细的步骤、指导意义以及示例代码。

    10 天前

相关推荐

    暂无文章