在 GraphQL 中使用联合类型的最佳实践

AI 编程助手,豆包旗下的编程助手,提供智能补全、智能预测、智能问答等能力,节省开发时间,释放脑海中的创造力,支持 VSCode,点击体验 AI

什么是联合类型

联合类型(Union Type)在 GraphQL 中是一种非常重要的数据类型。它允许我们定义一个字段可以返回多种不同的类型,这些类型可能是完全不同的,但是它们都具有相同的字段或特征,而且它们之间是相互竞争或互斥的。

例如:假设我们要定义一个 search 查询,它需要返回 UserMovie 两种类型,但是这两种类型分别属于不同的数据集合。在这种情况下,我们可以利用联合类型来解决问题。定义如下:

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

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

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

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

在上面的查询定义中,SearchResult 联合类型可以包含 UserMovie 两种类型,search 查询可以返回一个 SearchResult 数组。当客户端请求查询时,服务器根据查询的参数以及条件,决定要返回的结果是 User 还是 Movie

明白了联合类型的基本概念和用途之后,我们接下来可以看看在实际开发中如何使用这种类型。

在实际开发中如何使用联合类型

声明

在声明联合类型时,只需要通过 union 关键字,列举出所包含类型即可。

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

需要注意的是:联合类型只能包含对象类型,即类型 UserMovie 必须是 GraphQL 中的对象类型,不能是标量类型。

使用

联合类型的使用非常灵活,可以用于定义返回类型、变量类型、参数类型等等。以下是一些基本的使用方法。

查询

查询是 GraphQL 中最常用的操作之一,使用联合类型可以更方便地处理多种类型的查询结果。

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

在上面的查询定义中,参数 query 是查询参数,返回值是 [SearchResult!]! 类型的数组,这个数组包含多种类型的结果。

变量

在 GraphQL 中,联合类型也可以用于定义变量类型,这样变量就可以接受多种类型的输入。

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

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

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

在上面的示例中,SearchResultInput 是一个输入类型,包含 idtype 两个字段,其中 type 的类型是枚举类型 SearchResultType,这个枚举类型包含了 USERMOVIE 两个值,用于区分联合类型的不同类型。updateSearchResult 是一个更新类型,参数 result 的类型是 SearchResultInput,返回类型是 SearchResult

联合类型在查询结果中的定义

在 GraphQL 中,查询结果必须声明出所有可能的返回值类型,以便客户端进行类型推断。在联合类型中,我们可以使用关键词 ...on 来列举出联合类型中包含的所有类型。

假设我们要实现一个简单的搜索引擎,查询结果为 UserMovie,并且在前端中需要根据不同的类型分别显示不同的信息。在这种情况下,我们可以使用 ...on 定义不同的类型。

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

在上面的查询中,$query 是查询参数,查询 search 返回的结果包含多种类型,使用 ... on 列举出不同类型的字段。当客户端请求时,服务器根据查询参数,决定返回的结果是 User 还是 Movie

手动处理联合类型

虽然 ... on 可以帮我们自动处理联合类型,但是有时候我们需要手动操作联合类型,这时候就需要了解 GraphQL 中的一些内置函数。以下是一些常用的内置函数。

  • __typename:返回当前对象的类型名称,用于区分联合类型的不同类型。
  • __typename... on 结合使用,用于手动处理联合类型。

例如:

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

在上面的查询中,我们手动添加了 __typename 对象,并将 UserMovie 两种类型分开进行处理。

联合类型的最佳实践

在实际开发中,为了使联合类型更加灵活和易用,我们需要遵循一些最佳实践。

统一命名规范

联合类型可能包含多种不同的类型,其中每种类型都可能有自己的属性和方法。为了方便客户端进行开发和维护,我们需要对不同类型的属性和方法进行统一的命名规范。

例如:假设我们要定义一个联合类型 SearchResult,其中包含多种类型:UserMovie。为了方便客户端直接使用类型的属性和方法,我们需要为每个类型编写特定的方法,用于统一属性和方法的名称。

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

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

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

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

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

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

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

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

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

在上面的示例中,我们为每个类型定义了一个 SearchResultInterface 接口,这个接口包含三个字段:idnametitleSearchResultUserSearchResultMovieSearchResult 联合类型中的具体类型,分别用于表示 UserMovie 两种类型。

最后,我们还定义了一个 SearchResultListItem 类型,它包含一个 __typename 字段和一个 data 字段,用于向客户端返回数据。

对数据集合进行分类

在设计联合类型时,我们应该遵循 聚合(composition) 模式,即将不同类型的数据集合进行分类。具体来说,将不同类型的数据集合放在不同的 GraphQL 对象中,然后再定义一个联合类型来引用这些对象。

例如:假设我们有两个数据集合:UserMovie。这两个数据集合虽然拥有相同的字段,但是它们是完全不同的对象,用于不同的场景。在这种情况下,我们应该将它们放在不同的对象中,然后再定义一个联合类型 SearchResult 引用这些对象。

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

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

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

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

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

在上面的示例中,我们将 UserMovie 放在不同的对象中,然后再定义了一个联合类型 SearchResult,用于表示这两种类型之间的相似性。

避免类型耦合

为了避免类型耦合,我们需要将联合类型和接口进行分离,避免将联合类型和某个具体接口耦合在一起。这样可以增加代码的维护性,并更容易添加新的类型。

例如:假设我们有两个数据集合:UserMovie,它们都有各自的属性和方法。为了避免将联合类型和某个具体接口耦合在一起,我们需要将 UserMovie 分别放在不同的对象中,然后再定义两个接口 UserInterfaceMovieInterface,用于定义属性和方法。最后定义一个联合类型 SearchResult 引用这两个接口。

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

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

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

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

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

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

在上面的示例中,我们将 UserMovie 分别放在不同的对象中,然后定义了两个接口 UserInterfaceMovieInterface,用于定义属性和方法。最后定义一个联合类型 SearchResult 引用这两个接口。

结论

联合类型是 GraphQL 中非常重要的一种数据类型,它可以让我们更加灵活地处理具有多样性的数据集合。要善于运用联合类型,我们需要了解联合类型的基本知识和使用技巧,同时还需要遵循一些最佳实践,例如统一命名规范、对数据集合进行分类、避免类型耦合等。只有这样,我们才能更加灵活地使用 GraphQL 接口,更好地提供服务。

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


猜你喜欢

  • ECMAScript 2020 中新增的全局命名空间:globalThis

    在 ECMAScript 2020 中,我们迎来了一个新的全局命名空间:globalThis。它解决了 JavaScript 中跨环境访问全局对象的问题,并且为跨平台和多环境开发提供了更好的支持。

    13 天前
  • 如何使用 Jest 测试 React Native 中的动画

    React Native 是一个可跨平台运行的应用程序框架,它使用 JavaScript 和 React 来构建真正的移动应用程序。其中一个重要的特性就是它可以使用动画来提升用户体验。

    13 天前
  • 使用 Babel 编译 ES6 代码时如何支持打包成 iife 模块

    前言 ES6 是目前前端开发中使用最广泛的 Javascript 版本之一。但是,在一些旧版浏览器中,可能无法支持 ES6 的语法。因此,我们需要在项目中使用 Babel 来将 ES6 代码转换为 E...

    13 天前
  • React Hooks 详解 ——useEffect

    React Hooks 是 React 16.8 中引入的一组新特性,可以让 React 函数组件拥有类组件的能力,同时使得组件逻辑复用更加容易。其中 useEffect 是 React Hooks ...

    13 天前
  • 响应式设计实现中如何优化网页的 SEO 优化?

    随着移动设备的普及,越来越多的用户使用手机、平板电脑等移动设备来访问网站,这就要求我们的网页设计必须具备响应式布局,也就是能够自适应不同屏幕大小的设备。同时,我们还需要注意网站的 SEO 优化,以提高...

    13 天前
  • ES6 中的新特性 ——for-await-of

    ES6 中的新特性 ——for-await-of ES6 中引入了很多新特性,其中一个值得注意的是 for-await-of。该特性可以在异步处理数据集合时使用,能够在循环中依次获取 Promise ...

    13 天前
  • 使用 Next.js 实现微服务的最佳实践

    随着微服务架构的流行,越来越多的应用程序将用户界面和后端业务逻辑分离。对于前端团队来说,这意味着需要使用不同的技术来构建应用程序,以及使用新的方法来处理数据和服务。

    13 天前
  • Chai 如何对 HTTP 请求进行测试?

    Chai 如何对 HTTP 请求进行测试? 前端开发中,我们经常需要对 API 的数据请求和响应进行测试。Mocha 是一个灵活的 JavaScript 测试框架,Chai 是一个用于编写断言的 Ja...

    13 天前
  • Node.js 中使用 Gulp 实现前端自动化构建

    随着前端开发的日益复杂,传统的手动构建已经无法满足开发效率和质量的要求。而自动化构建则成为现代前端工程化的必要手段之一。Gulp 是一个流式构建工具,其简单易用和灵活可扩展的特点使其在前端自动化构建领...

    13 天前
  • 如何在 PWA 应用中添加简单的图像滤镜效果

    在现代网络应用程序开发中,PWA(渐进式网络应用程序)已经成为一个流行的技术解决方案,它可以使 web 应用程序具有原生应用程序的功能。其中一个关键特性是可以在离线状态下访问 web 应用程序。

    13 天前
  • Socket.io 如何实现群聊

    Socket.io 是一个基于 Node.js 的实时应用程序框架,可以轻松地为 Web 应用程序添加双向通信功能,例如实时聊天和实时数据分析。 在本文中,我们将探讨如何使用 Socket.io 实现...

    13 天前
  • 使用 LESS 进行快速、模块化和维护性高的 CSS

    CSS 是网页开发中必不可少的一部分,但是当项目变得越来越庞大时,CSS 可能会变得难以维护和更新。此时,LESS 的出现可以让我们更加高效地编写 CSS,进行模块化管理和提高代码可读性。

    13 天前
  • Serverless 架构下如何实现自动化测试

    随着云计算和无服务器架构的发展,越来越多的应用已经迁移到了无服务器架构上。在这种情况下,如何实现自动化测试以保证应用的可靠性和稳定性成为诸多前端开发人员关注的问题。

    13 天前
  • Deno 下性能优化的手段与技巧

    Deno 是一款现代的 JavaScript 和 TypeScript 运行时环境,它是由 Node.js 的创造者 Ryan Dahl 设计的。与 Node.js 不同的是,Deno 采用了 V8 ...

    13 天前
  • 解决 AngularJS 显示不出图片的问题

    如何解决 AngularJS 显示不出图片的问题 在 AngularJS 中,显示图片是一个重要的功能,特别是在开发中需要展示大量的图片时。但是,有时会遇到显示图片失败的问题,导致无法正常显示图片。

    13 天前
  • ECMAScript 2021 (ES12) 中的 BigInt 数据类型,应对大整数计算

    在传统的 JavaScript 中,数字的最大值为 2 的 53 次方。对于大于该值的计算,传统的 Number 数据类型将产生精度丢失等问题。为了解决这些问题,ECMAScript 2021 (ES...

    13 天前
  • 使用 Mocha 从零开始构建一个完整的 Node.js 应用测试框架

    在 Node.js 中,测试是非常重要的一环。测试能够确保我们的代码正确运行,同时也能加速我们的开发过程。而 Mocha 则是 Node.js 最流行的测试框架之一。

    13 天前
  • Kubernetes 中的 Job 和 CronJob 的使用

    随着 Kubernetes 的普及和使用,Job 和 CronJob 成为了管理容器化应用程序的重要工具。这两个资源对象允许我们在 Kubernetes 上安排一次性任务或定期重复任务的运行。

    13 天前
  • 如何编写高效的 Redux 中间件

    Redux 中间件是 Redux 核心概念中的一个重要组成部分,它允许开发者在 Redux 的 Action 发送和 Reducer 处理过程中添加自定义逻辑。 在实际的项目中,我们通常需要使用 Re...

    13 天前
  • Headless CMS 在全球化应用中的应用场景分析

    Headless CMS 是指将内容管理与展示分离的一种 CMS 架构,它的特点是将内容作为数据存储,并通过 API 提供给前端,以便前端可以自由定制界面和样式。在多语言和全球化应用中,Headles...

    13 天前

相关推荐

    暂无文章