GraphQL
GraphQL | A query language for your API
https://graphql.org/GraphQL 是一种用于 API 的查询语言,也是一种服务器端运行时,用于使用您为自己定义的类型系统执行查询 数据。 GraphQL 不依赖于任何特定的数据库或存储引擎,而是由您现有的代码和数据支持。type Query {
me: User
}
type User {
id: ID
name: String
}
以及每种类型的每个字段的功能:
function Query_me(request) {
return request.auth.user;
}
function User_name(user) {
return user.getName();
}
GraphQL 服务运行后(通常在 Web 服务上的 URL 处),它可以接收 GraphQL 查询以进行验证和执行。 该服务首先检查查询以确保它仅引用定义的类型和字段,然后运行提供的函数 产生一个结果。
例如,查询:
{
me {
name
}
}
可以产生以下 JSON 结果:
{
"me": {
"name": "Luke Skywalker"
}
}
字段
最简单的,GraphQL 是关于询问对象的特定字段。 让我们从一个非常简单的查询和运行它时得到的结果开始:
The field name
returns a String
type, in this case the name of the main hero of Star Wars, "R2-D2"
.
在前面的示例中,我们只询问了返回 String 的英雄的名字,但字段也可以引用 Objects。 在这种情况下,您可以 子选择 为该对象进行字段 GraphQL 查询可以遍历相关对象及其字段,让客户端在一个请求中获取大量相关数据,而不是像经典 REST 架构中那样进行多次往返。
参数
如果我们唯一能做的就是遍历对象及其字段,那么 GraphQL 已经是一种非常有用的数据获取语言。 但是,当您添加将参数传递给字段的功能时,事情会变得更加有趣。
在像 REST 这样的系统中,您只能传递一组参数——请求中的查询参数和 URL 段。 但是在 GraphQL 中,每个字段和嵌套对象都可以获取自己的一组参数,这使得 GraphQL 完全替代了进行多个 API 获取。 您甚至可以将参数传递给标量字段,以便在服务器上实现一次数据转换,而不是分别在每个客户端上实现。
参数可以有许多不同的类型。 在上面的示例中,我们使用了 Enumeration 类型,它表示一组有限的选项之一(在这种情况下,长度单位,或者 METER
或者 FOOT
)。 GraphQL 带有一组默认类型,但 GraphQL 服务器也可以声明自己的自定义类型,只要它们可以序列化为您的传输格式。 Schemas and Types | GraphQL
Aliases
如果你有敏锐的眼光,你可能已经注意到,由于结果对象字段与查询中的字段名称匹配但不包含参数,因此不能直接查询具有不同参数的同一字段。 这就是您需要 别名 - 它们让您可以将字段的结果重命名为您想要的任何内容。
假设我们的应用中有一个相对复杂的页面,可以让我们并排查看两个英雄以及他们的朋友。 您可以想象这样的查询很快就会变得复杂,因为我们需要至少重复一次字段 - 比较的每一侧都有一个。
fragment
这就是 GraphQL 包含称为 片段 。 片段让您可以构建字段集,然后将它们包含在您需要的查询中。 这是一个如何使用片段解决上述情况的示例:
查询结果:您可以看到如果重复字段,上述查询将如何重复。 片段的概念经常用于将复杂的应用程序数据需求拆分为更小的块,尤其是当您需要将许多具有不同片段的 UI 组件组合到一个初始数据提取中时。
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
},
{
"name": "C-3PO"
},
{
"name": "R2-D2"
}
]
},
"rightComparison": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
片段可以访问查询或突变中声明的变量
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"friendsConnection": {
"totalCount": 4,
"edges": [
{
"node": {
"name": "Han Solo"
}
},
{
"node": {
"name": "Leia Organa"
}
},
{
"node": {
"name": "C-3PO"
}
}
]
}
},
"rightComparison": {
"name": "R2-D2",
"friendsConnection": {
"totalCount": 3,
"edges": [
{
"node": {
"name": "Luke Skywalker"
}
},
{
"node": {
"name": "Han Solo"
}
},
{
"node": {
"name": "Leia Organa"
}
}
]
}
}
}
}
到目前为止,我们一直在使用简写语法,我们省略了 query
关键字和查询名称,但在生产应用程序中,使用它们可以使我们的代码不那么模棱两可。
这是一个包含关键字的示例 query
作为 操作类型 和 HeroNameAndFriends
作为 操作名称 :
GraphQL 有一种一流的方式将动态值从查询中分解出来,并将它们作为单独的字典传递。 这些值称为 变量 。
当我们开始使用变量时,我们需要做三件事:
- 将查询中的静态值替换为
$variableName
- 宣布
$variableName
作为查询接受的变量之一 - 经过
variableName: value
在单独的、特定于传输的(通常是 JSON)变量字典中
这是它的样子: