原文链接:The Anatomy of a GraphQL Query GraphQL 日渐成为数据查询的主流标准之一,整个生态圈也蓬勃发展。本文则由浅入深地详细介绍基础的 GraphQL 格式与关键字,有助于初学者对于 GraphQL 的使用形成体系认知。
GraphQL 日渐成为数据查询的主流标准之一。每天都会产生许多围绕这项技术发展的精彩讨论和新工具。GraphQL最棒的特性就是提供了一个丰富语言集来描述获取数据的API。但是用户该如何描述这种查询语言,以及GraphQL这项核心技术本身呢?let's talk!
GraphQL specification解释了几乎所有出现在GraphQL查询语言中的概念,但是这篇文档实在是太长了,所以我准备在这篇博客中,借助一些具体的栗子来阐述其中一些最重要的概念,来帮助你成为GraphQL专家!至少在纸上谈兵方面 : )
注! 这篇文章可不是GraphQL的入门读物。首先,你应该通读concepts on the graphql.org docs,然后通过Learn Apollo tutorial来学习使用GraphQL,最后当你想继续深入了解这项技术时,再回到这里来吧!
大家通常会使用“查询”来称呼 GraphQL API 服务的一切。但是这样称呼会有太多东西混杂在一起了。我们可能会把我们跪求服务端的一系列行为称为一次查询、一次修改或者一次订阅,但我想“请求(request)”这个词可能更加复合HTTP通信的概念,下面我们先来定义一些最基础的概念:
为了搞清楚GraphQL各种基本操作之间的区别,让我们先来看一个简单的GraphQL请求体:
GraphQL document
<center>A simple query and its parts.</center>
这个请求体显示了GraphQL的主要构建块,它指定了你尝试获取的数据。
为了让你以非常简洁的形式定义一个GraphQL查询,上面的栗子是GraphQL的一种非常简单的形式。但是在GraphQL操作中三种可选的部分都没有在上述栗子中使用。如果你不仅仅是用GraphQL执行查询操作,或是希望传递动态变量到GraphQL查询中,你就需要利用到这些新的GraphQL特性。
这里恰好有一个包含了所有可选部分的栗子:
A more detailed query and its parts.
<center>A more detailed query and its parts.</center>
变量使用特定的序列化协议(在目前的 GraphQL 服务实现中,通常是使用JSON )通过查询文档独立传输。下面是一个变量对象在查询文档中的示例:
An example variables object.
<center>An example variables object.</center>
可以看到,这里的关键是变量名称需要与变量定义所匹配,其名称是Episode
枚举中的一个成员。
这里有一个在谈及Graph的技术意义时很重要,却不常被提及的核心概念——花括号之间的所有东西叫什么?
选择集(selection set)是一个会在GraphQL 文档中经常出现的概念,它赋予了GraphQL递归的特性,允许你获取嵌套形式的数据。
Int
或者String
。当开始介绍片段(fragments)之后,GraphQL 将变得更加强大。它带来了一系列新的概念。
Fragments
<center>A fragment definition and its parts.</center>
就像操作(operations)一样,片段也选择集,使用起来也跟在操作(operations)中使用选择集一样。
片段(fragments )只有在操作(operations)中使用才能发挥出作用。片段是 GraphQL 的主要组合数据结构,通过片段可以重用重复的字段选择,减少 query 中的重复内容。接下来我们将介绍使用片段(fragments )的两种方式:
fragments
...
之后来表示片段。例如没有片段时需要这样编写 query:query noFragments {
user(id: 4) {
friends(first: 10) {
id
name
profilePic(size: 50)
}
mutualFriends(first: 10) {
id
name
profilePic(size: 50)
}
}
}
query 中存在下列重复的选择集合:
{
id
name
profilePic(size: 50)
}
可以用片段简化为:
query withFragments {
user(id: 4) {
friends(first: 10) {
...friendFields
}
mutualFriends(first: 10) {
...friendFields
}
}
}
fragment friendFields on User {
id
name
profilePic(size: 50)
}
使用片段时需要加上 ... 操作符表示展开片段内容,这称为片段扩展运算符(fragment spread),它可以用在任何选择集(selection set)中,用以匹配片段的类型条件。
skip(忽略)
和include(包括)
两个指令。 Directives <center>You probably wouldn’t usually put all of these in one query, but it’s the easiest way to demonstrate.</center> 你能在上文厨房水槽的栗子中使用指令`skip` 和 `include`。`include` 指令表示只有在 if 参数为 true 时才引入片段表示的字段。`skip` 指令表示在 if 参数为 true 时忽略片段中的字段。由于指令的语法相当灵活,我们可以利用它来给GraphQL添加更多的特性,而不是使用语法解析或者引入更复杂的工具的方式。
include
指令表示只有在 if 参数为 true 时才引入片段表示的字段。skip
指令表示在 if 参数为 true 时忽略片段中的字段。