GraphQL BEST PRACTICES:查询和复杂操作功能

本文主要介绍GraphQL如何通过查询和复杂查询GraphQL Server获取需要的数据结果。具体请参考原文

https://graphql.org/learn/queries/

Fields字段

最简单的说,GraphQL是关于请求对象上的特定字段。让我们先看看一个非常简单的查询,以及运行它时得到的结果:

Snip20191108_8

返回结果hero添加friends对象和它的name字段

Snip20191108_9

Arguments查询参数

如果我们唯一能做的就是遍历对象及其字段,GraphQL就已经是一种非常有用的数据获取语言了。但是,当您添加了向字段传递参数的能力时,事情会变得更加有趣。

Snip20191108_10

查询Human id为1000,返回身高使用单位英尺(长度,米或英尺)

Snip20191108_11

Aliases别名

如果您有敏锐的眼光,您可能已经注意到,由于结果对象字段与查询中字段的名称匹配,但不包含参数,因此不能直接查询具有不同参数的同一字段。这就是为什么你需要别名-它们允许你将一个字段的结果重命名为任何你想要的。

Snip20191108_12

在上面的例子中,两个hero字段会有冲突,但是由于我们可以将它们命名为不同的名称,所以我们可以在一个请求中同时得到这两个结果。

Fragments片段

假设我们的应用程序中有一个相对复杂的页面,让我们可以看到两个英雄和他们的朋友在一起您可以想象,这样的查询可能会很快变得复杂,因为我们需要至少重复一次字段—对比较的每一侧重复一次。

这就是GraphQL包含可重用单元fragments的原因。片段允许您构造字段集,然后在需要的地方将它们包含在查询中下面是一个使用片段解决上述情况的示例:

Snip20191108_13

您可以看到,如果重复这些字段,上面的查询将非常重复。片段的概念经常用于将复杂的应用程序数据需求分割成更小的块,特别是当需要将许多具有不同片段的UI组件组合成一个初始数据获取时。

Using variables inside fragments片段中使用变量

片段可以访问查询或复杂查询中声明的变量。

Snip20191108_14

Operation name操作名称

到目前为止,我们一直在使用速记语法,省略查询关键字和查询名称,但在生产应用程序中,使用这些语法可以减少代码的歧义。

Snip20191108_15

操作类型可以是查询、变异或订阅,并描述要执行的操作类型。操作类型是必需的,除非使用的是查询速记语法,在这种情况下,不能为操作提供名称或变量定义。

操作名是操作的有意义的显式名称它只在多操作文档中需要,但由于它对调试和服务器端日志记录非常有帮助,因此鼓励使用它当网络日志或GraphQL服务器出错时,按名称标识代码库中的查询比试图破译内容更容易把它想象成你最喜欢的编程语言中的函数名例如,在JavaScript中,我们可以很容易地只使用匿名函数,但是当我们给一个函数命名时,跟踪它、调试代码和在调用它时记录日志就更容易了以同样的方式,GraphQL查询和变异名以及片段名可以成为服务器端识别不同GraphQL请求的有用调试工具。

Variables变量

到目前为止,我们一直在查询字符串中写入所有参数。但在大多数应用程序中,字段的参数是动态的:例如,可能有一个下拉列表,让您选择您感兴趣的星球大战插曲、搜索字段或一组过滤器。

直接在查询字符串中传递这些动态参数不是一个好主意,因为这样我们的客户端代码就需要在运行时动态地操作查询字符串,并将其序列化为特定于GraphQL的格式。相反,GraphQL有一个一流的方法将动态值从查询中分离出来,并将它们作为单独的字典传递这些值称为变量。

当我们开始处理变量时,我们需要做三件事:

1.将查询中的静态值替换为$variableName
2.将$variableName声明为查询接受的变量之一
3.Pass variableName:在单独的、特定于传输的(通常是JSON)变量字典中的值
Snip20191108_16现在,在我们的客户端代码中,我们只需传递一个不同的变量,而不需要构造一个全新的查询。一般来说,这也是表示查询中哪些参数是动态的一个良好实践-我们不应该使用字符串插值来根据用户提供的值构造查询。

Variable definitions变量定义

变量定义是上面查询中看起来像($seeption:seeption)的部分它的工作方式与类型语言中函数的参数定义类似。在本例中,它列出了所有变量,前缀是$,后面是它们的类型。

所有声明的变量必须是标量、枚举或输入对象类型因此,如果要将复杂对象传递到字段中,则需要知道服务器上匹配的输入类型了解有关架构页上的输入对象类型的详细信息。

变量定义可以是可选的,也可以是必需的在上面的例子中,因为没有!在插曲类型旁边,它是可选的但是,如果要将变量传递到的字段需要一个非空参数,那么也必须需要该变量。

要进一步了解这些变量定义的语法,学习GraphQL模式语言很有用。模式语言在模式页上有详细说明。

Default variables变量缺省值

通过在类型声明之后添加默认值,也可以将默认值分配给查询中的变量。

Snip20191108_18
当为所有变量提供默认值时,可以调用查询而不传递任何变量。如果任何变量作为变量字典的一部分传递,它们将覆盖默认值。

Directives指令

我们在上面讨论了变量如何使我们避免使用手动字符串插值来构造动态查询。在参数中传递变量可以解决相当大的一类问题,但是我们可能还需要一种方法来使用变量动态地更改查询的结构和形状。例如,我们可以想象一个UI组件有一个总结和详细的视图,其中一个包含比另一个更多的字段。

Snip20191108_19

我们需要在GraphQL中使用一个称为指令的新特性指令可以附加到字段或片段包含,并且可以以服务器希望的任何方式影响查询的执行。核心GraphQL规范正好包含两个指令,任何符合规范的GraphQL服务器实现都必须支持这两个指令:

@include(if:Boolean)仅当参数为true时在结果中包含此字段。
@skip(if:Boolean)如果参数为true,则跳过此字段。
指令对于摆脱在查询中添加和删除字段时需要进行字符串操作的情况非常有用服务器实现还可以通过定义全新的指令来添加实验特性。

Mutations复杂操作

大多数关于GraphQL的讨论都集中在数据获取上,但是任何完整的数据平台都需要一种修改服务器端数据的方法。

在REST中,任何请求最终都可能会对服务器造成一些副作用,但按照惯例,建议不要使用GET请求来修改数据GraphQL是类似的-从技术上讲,任何查询都可以实现以导致数据写入。但是,建立一个约定很有用,即任何导致写操作的操作都应该通过变异显式地发送。

就像在查询中一样,如果变异字段返回对象类型,则可以请求嵌套字段这对于在更新后获取对象的新状态非常有用让我们来看一个简单的突变示例:

Snip20191108_20

Multiple fields in mutations多个字段复杂操作

变异可以包含多个字段,就像查询一样。查询和突变之间有一个重要的区别,除了名称:

当查询字段并行执行时,复杂操作字段一个接一个地串行运行。

这意味着,如果我们在一个请求中发送两个incrementCredits复杂操作,那么第一个请求将保证在第二个请求开始之前完成,从而确保我们不会以自己的状况结束。

Inline Fragments内联片段

与许多其他类型系统一样,GraphQL模式包括定义接口和联合类型的能力在模式指南中了解它们。

如果查询返回接口或联合类型的字段,则需要使用内联片段访问底层具体类型上的数据。

Meta fields元字段

考虑到有些情况下,您不知道从GraphQL服务返回的类型,您需要某种方法来确定如何在客户端处理该数据GraphQL允许您在查询中的任意点请求元字段__typename,以获取该点上对象类型的名称。

Snip20191108_22

 

推荐文章

沪公网安备 31010702002009号