结构和类型
¥Schemas and Types
Learn about the different elements of the GraphQL type system
GraphQL 类型系统 描述了可以从 API 查询哪些数据。这些功能的集合称为服务的模式,客户端可以使用该模式向 API 发送返回可预测结果的查询。
¥The GraphQL type system describes what data can be queried from the API. The collection of those capabilities is referred to as the service’s schema and clients can use that schema to send queries to the API that return predictable results.
在此页面上,我们将探索 GraphQL 的 六种命名类型定义 以及类型系统的其他功能,以了解如何使用它们来描述你的数据及其之间的关系。由于 GraphQL 可以与任何后端框架或编程语言一起使用,我们将避免特定于实现的细节,只讨论概念。
¥On this page, we’ll explore GraphQL’s six kinds of named type definitions as well as other features of the type system to learn how they may be used to describe your data and the relationships between them. Since GraphQL can be used with any backend framework or programming language, we’ll avoid implementation-specific details and talk only about the concepts.
类型系统
¥Type system
如果你以前见过 GraphQL 查询,你就会知道 GraphQL 查询语言基本上是关于选择对象上的字段。因此,例如,在以下查询中:
¥If you’ve seen a GraphQL query before, you know that the GraphQL query language is basically about selecting fields on objects. So, for example, in the following query:
-
我们从一个特殊的 “root” 对象开始
¥We start with a special “root” object
-
我们选择
hero
字段¥We select the
hero
field on that -
对于
hero
返回的对象,我们选择name
和appearsIn
字段¥For the object returned by
hero
, we select thename
andappearsIn
fields
由于 GraphQL 查询的形状与结果非常匹配,因此我们可以预测查询将返回什么,而无需了解太多有关服务器的信息。但对我们可以请求的数据有一个准确的描述是很有用的。例如,我们可以选择哪些字段?他们可能返回什么类型的对象?这些子对象有哪些可用字段?
¥Because the shape of a GraphQL query closely matches the result, we can predict what the query will return without knowing that much about the server. But it’s useful to have an exact description of the data we can request. For example, what fields can we select? What kinds of objects might they return? What fields are available on those sub-objects?
这就是结构的用武之地。每个 GraphQL 服务都定义了一组类型,这些类型完全描述了我们可以在该服务上查询的可能数据集。然后,当请求进入时,将根据该模式对其进行验证和执行。
¥That’s where the schema comes in. Every GraphQL service defines a set of types that completely describe the set of possible data we can query on that service. Then, when requests come in, they are validated and executed against that schema.
类型语言
¥Type language
GraphQL 服务可以用任何语言编写,在模式中定义类型时,你可以采用多种不同的方法:
¥GraphQL services can be written in any language and there are many different approaches you can take when defining the types in a schema:
-
有些库让你使用与编写 GraphQL 实现相同的编程语言一起构建模式类型、字段和解析器函数。
¥Some libraries have you construct the schema types, fields, and resolver functions together using the same programming language that was used to write the GraphQL implementation.
-
有些库允许你使用通常称为模式定义语言(或 SDL)的语言更符合人机工程学地定义类型和字段,然后分别为相应字段编写解析器函数。
¥Some libraries allow you to define types and fields more ergonomically using what’s commonly called the schema definition language (or SDL) and then write the resolver functions for the corresponding fields separately.
-
有些库允许你编写和注释解析器函数,然后从中推断模式。
¥Some libraries allow you to write and annotate the resolver functions, and then infer the schema from that.
-
有些库甚至可能根据一些底层数据源为你推断类型和解析器函数。
¥Some libraries may even infer both the types and resolver functions for you, based on some underlying data source(s).
由于我们不能依赖特定的编程语言来在本指南中讨论 GraphQL 模式,因此我们将使用 SDL,因为它类似于我们迄今为止看到的查询语言,并允许我们以与语言无关的方式讨论 GraphQL 模式。
¥Since we can’t rely on a specific programming language to discuss GraphQL schemas in this guide, we’ll use SDL because it’s similar to the query language that we’ve seen so far and allows us to talk about GraphQL schemas in a language-agnostic way.
对象类型和字段
¥Object types and fields
GraphQL 模式的最基本组件是 对象类型,它仅表示你可以从服务中获取的一种对象,以及它具有哪些字段。在 SDL 中,我们这样表示:
¥The most basic components of a GraphQL schema are Object types, which just represent a kind of object you can fetch from your service, and what fields it has. In SDL, we represent it like this:
type Character {
name: String!
appearsIn: [Episode!]!
}
该语言是可读的,但让我们回顾一下,以便我们可以拥有一个共享的词汇表:
¥The language is readable, but let’s go over it so that we can have a shared vocabulary:
-
Character
是 GraphQL 对象类型,这意味着它是一种具有一些字段的类型。架构中的大多数类型都是对象类型。¥
Character
is a GraphQL Object type, meaning it’s a type with some fields. Most of the types in your schema will be Object types. -
name
和appearsIn
是Character
类型上的 fields。这意味着name
和appearsIn
是唯一可以出现在对Character
类型进行操作的 GraphQL 查询的任何部分中的字段。¥
name
andappearsIn
are fields on theCharacter
type. That means thatname
andappearsIn
are the only fields that can appear in any part of a GraphQL query that operates on theCharacter
type. -
String
是内置 标量类型 之一。这些类型解析为单个标量值,并且在查询中不能有子选择。我们稍后会详细介绍标量类型。¥
String
is one of the built-in Scalar types. These are types that resolve to a single scalar value and can’t have sub-selections in the query. We’ll go over Scalar types more later. -
String!
表示该字段是 非空类型,这意味着 GraphQL 服务承诺在你查询此字段时为你提供一个值。在 SDL 中,我们用感叹号表示。¥
String!
means that the field is a Non-Null type, meaning the GraphQL service promises to give you a value whenever you query this field. In SDL, we represent those with an exclamation mark. -
[Episode!]!
表示Episode
对象的 列表类型。当列表非空时,查询appearsIn
字段时总是可以得到一个数组(包含零个或多个项目)。在这种情况下,由于Episode!
在列表中也是非空的,因此你始终可以期望数组中的每个项目都是Episode
对象。¥
[Episode!]!
represents an List type ofEpisode
objects. When a List is Non-Null, you can always expect an array (with zero or more items) when you query theappearsIn
field. In this case, sinceEpisode!
is also Non-Null within the list, you can always expect every item in the array to be anEpisode
object.
现在你知道 GraphQL 对象类型是什么样的以及如何读取 SDL 的基础知识。
¥Now you know what a GraphQL Object type looks like and how to read the basics of SDL.
参数
¥Arguments
GraphQL 对象类型上的每个字段都可以有零个或多个 arguments,例如下面的 length
字段:
¥Every field on a GraphQL Object type can have zero or more arguments, for example, the length
field below:
type Starship {
id: ID!
name: String!
length(unit: LengthUnit = METER): Float
}
所有参数均已命名。与 JavaScript 和 Python 等语言不同,在这些语言中函数采用有序参数列表,而 GraphQL 中的所有参数都是通过名称传递的。在这种情况下,length
字段有一个定义的参数,称为 unit
。
¥All arguments are named. Unlike languages such as JavaScript and Python where functions take a list of ordered arguments, all arguments in GraphQL are passed by name specifically. In this case, the length
field has one defined argument called unit
.
参数可以是必需的,也可以是可选的。当参数是可选的时,我们可以定义一个默认值。如果未传递 unit
参数,则默认情况下它将设置为 METER
。
¥Arguments can be either required or optional. When an argument is optional, we can define a default value. If the unit
argument is not passed, then it will be set to METER
by default.
查询、变异和订阅类型
¥The Query, Mutation, and Subscription types
每个 GraphQL 模式都必须支持 query
操作。此 根操作类型 的入口点是默认情况下称为 Query
的常规对象类型。因此,如果你看到如下所示的查询:
¥Every GraphQL schema must support query
operations. The entry point for this root operation type is a regular Object type called Query
by default. So if you see a query that looks like this:
这意味着 GraphQL 服务需要具有带有 droid
字段的 Query
类型:
¥That means that the GraphQL service needs to have a Query
type with a droid
field:
type Query {
droid(id: ID!): Droid
}
架构还可以通过添加其他 Mutation
和 Subscription
类型然后在相应的根操作类型上定义字段来支持 mutation
和 subscription
操作。
¥Schemas may also support mutation
and subscription
operations by adding additional Mutation
and Subscription
types and then defining fields on the corresponding root operation types.
重要的是要记住,除了作为架构入口点的特殊状态外,Query
、Mutation
和 Subscription
类型与任何其他 GraphQL 对象类型相同,并且它们的字段的工作方式完全相同。
¥It’s important to remember that other than the special status of being entry points into the schema, the Query
, Mutation
, and Subscription
types are the same as any other GraphQL Object type, and their fields work exactly the same way.
你也可以为根操作类型命名不同的名字;如果你选择这样做,则需要使用 schema
关键字将新名称通知 GraphQL:
¥You can name your root operation types differently too; if you choose to do so then you will need to inform GraphQL of the new names using the schema
keyword:
schema {
query: MyQueryType
mutation: MyMutationType
subscription: MySubscriptionType
}
标量类型
¥Scalar types
GraphQL 对象类型具有名称和字段,但在某些时候,这些字段必须解析为一些具体的数据。这就是 标量类型 的用武之地:它们代表查询的叶值。
¥A GraphQL Object type has a name and fields, but at some point, those fields must resolve to some concrete data. That’s where the Scalar types come in: they represent the leaf values of the query.
在以下查询中,name
和 appearsIn
字段将解析为标量类型:
¥In the following query, the name
and appearsIn
fields will resolve to Scalar types:
我们知道这一点,因为这些字段没有任何子字段 - 它们是查询的叶子。
¥We know this because those fields don’t have any sub-fields—they are the leaves of the query.
GraphQL 附带一组开箱即用的 默认标量类型:
¥GraphQL comes with a set of default Scalar types out of the box:
-
Int
:有符号 32 位整数。¥
Int
: A signed 32‐bit integer. -
Float
:有符号双精度浮点值。¥
Float
: A signed double-precision floating-point value. -
String
:UTF-8 字符序列。¥
String
: A UTF‐8 character sequence. -
Boolean
:true
或false
。¥
Boolean
:true
orfalse
. -
ID
:唯一标识符,通常用于重新获取对象或作为缓存的键。ID
类型的序列化方式与String
相同;然而,将其定义为ID
意味着它不适合人类可读。¥
ID
: A unique identifier, often used to refetch an object or as the key for a cache. TheID
type is serialized in the same way as aString
; however, defining it as anID
signifies that it is not intended to be human‐readable.
在大多数 GraphQL 服务实现中,还有一种方法可以指定自定义标量类型。例如,我们可以定义一个 Date
类型:
¥In most GraphQL service implementations, there is also a way to specify custom Scalar types. For example, we could define a Date
type:
scalar Date
然后由我们的实现来定义如何序列化、反序列化和验证该类型。例如,你可以指定 Date
类型应始终序列化为整数时间戳,并且你的客户端应该知道任何日期字段都应采用该格式。
¥Then it’s up to our implementation to define how that type should be serialized, deserialized, and validated. For example, you could specify that the Date
type should always be serialized into an integer timestamp, and your client should know to expect that format for any date fields.
枚举类型
¥Enum types
枚举类型,也称为枚举类型,是一种特殊的标量,仅限于一组特定的允许值。这使你能够:
¥Enum types, also known as enumeration types, are a special kind of scalar that is restricted to a particular set of allowed values. This allows you to:
-
验证此类型的任何参数是否都是允许的值之一
¥Validate that any arguments of this type are one of the allowed values
-
通过类型系统传达字段始终是有限值集之一的信息
¥Communicate through the type system that a field will always be one of a finite set of values
以下是 SDL 中枚举类型定义的样子:
¥Here’s what an Enum type definition looks like in SDL:
enum Episode {
NEWHOPE
EMPIRE
JEDI
}
这意味着无论我们在结构中使用类型 Episode
,我们都希望它恰好是 NEWHOPE
、EMPIRE
或 JEDI
之一。
¥This means that wherever we use the type Episode
in our schema, we expect it to be exactly one of NEWHOPE
, EMPIRE
, or JEDI
.
类型修饰符
¥Type modifiers
在 GraphQL 中,类型默认为可空且单数。但是,当你在架构中(或在 查询变量声明 中)使用这些命名类型时,你可以应用会影响这些值含义的其他类型修饰符。
¥Types are assumed to be nullable and singular by default in GraphQL. However, when you use these named types in a schema (or in query variable declarations) you can apply additional type modifiers that will affect the meaning of those values.
如上例所示,GraphQL 支持两种类型修饰符 - 列表 和 非空 类型 - 它们可以单独使用,也可以相互组合使用。
¥As we saw with the Object type example above, GraphQL supports two type modifiers—the List and Non-Null types—and they can be used individually or in combination with each other.
非空
¥Non-Null
让我们看一个例子:
¥Let’s look at an example:
type Character {
name: String!
}
这里,我们使用 String
类型,并通过在类型名称后添加感叹号 (!
) 将其标记为非空类型。这意味着我们的服务器始终期望为此字段返回一个非空值,如果解析器生成一个空值,那么这将触发 GraphQL 执行错误,让客户端知道出了问题。
¥Here, we’re using a String
type and marking it as a Non-Null type by adding an exclamation mark (!
) after the type name. This means that our server always expects to return a non-null value for this field, and if the resolver produces a null value, then that will trigger a GraphQL execution error, letting the client know that something has gone wrong.
如上例所示,Non-Null 类型修饰符也可用于定义字段的参数,如果传递了空值作为该参数,GraphQL 服务器将返回验证错误:
¥As we saw in an example above, the Non-Null type modifier can also be used when defining arguments for a field, which will cause the GraphQL server to return a validation error if a null value is passed as that argument:
列表
¥List
列表以类似的方式工作。我们可以使用类型修饰符将类型标记为 List 类型,这表明该字段将返回该类型的数组。在 SDL 中,这通过将类型括在方括号中来表示,[
和 ]
。对于参数来说,它的工作方式相同,其中验证步骤将期望该值的数组。这是一个例子:
¥Lists work in a similar way. We can use a type modifier to mark a type as a List type, which indicates that this field will return an array of that type. In SDL, this is denoted by wrapping the type in square brackets, [
and ]
. It works the same for arguments, where the validation step will expect an array for that value. Here’s an example:
type Character {
name: String!
appearsIn: [Episode]!
}
如上所示,Non-Null 和 List 修饰符可以组合使用。例如,你可以有一个非空 String
类型的列表:
¥As we see above, the Non-Null and List modifiers can be combined. For example, you can have a List of Non-Null String
types:
myField: [String!]
这意味着列表本身可以为空,但不能有任何空成员。例如,在 JSON 中:
¥This means that the list itself can be null, but it can’t have any null members. For example, in JSON:
myField: null // valid
myField: [] // valid
myField: ["a", "b"] // valid
myField: ["a", null, "b"] // error
现在,假设我们定义了一个 String
类型的非空列表:
¥Now, let’s say we defined a Non-Null List of String
types:
myField: [String]!
这意味着列表本身不能为空,但它可以包含空值:
¥This means that the list itself cannot be null, but it can contain null values:
myField: null // error
myField: [] // valid
myField: ["a", "b"] // valid
myField: ["a", null, "b"] // valid
最后,你还可以拥有一个非空 String
类型的非空列表:
¥Lastly, you can also have a Non-Null List of Non-Null String
types:
myField: [String!]!
这意味着列表不能为空,也不能包含空值:
¥This means that the list cannot be null and it cannot contain null values:
myField: null // error
myField: [] // valid
myField: ["a", "b"] // valid
myField: ["a", null, "b"] // error
你可以根据需要任意嵌套任意数量的 Non-Null 和 List 修饰符。
¥You can arbitrarily nest any number of Non-Null and List modifiers, according to your needs.
[]
would still be a valid response for a Non-Null List of a Non-Null type.接口类型
¥Interface types
与许多类型系统一样,GraphQL 支持抽象类型。我们将要探索的第一个类型是 接口类型,它定义了一组特定的字段,具体对象类型或其他接口类型也必须包含这些字段才能实现它。
¥Like many type systems, GraphQL supports abstract types. The first of these types that we’ll explore is an Interface type, which defines a certain set of fields that a concrete Object type or other Interface type must also include to implement it.
例如,你可以有一个代表星球大战三部曲中任何角色的 Character
接口类型:
¥For example, you could have a Character
Interface type that represents any character in the Star Wars trilogy:
interface Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
这意味着任何实现 Character
的类型都需要具有这些精确的字段以及相同的参数和返回类型。
¥This means that any type that implements Character
needs to have these exact fields as well as the same arguments and return types.
例如,以下是一些可能实现 Character
的类型:
¥For example, here are some types that might implement Character
:
type Human implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
starships: [Starship]
totalCredits: Int
}
type Droid implements Character {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
primaryFunction: String
}
你可以看到,这两种类型都具有 Character
接口类型的所有字段,但也引入了特定于该特定类型字符的额外字段 - totalCredits
、starships
和 primaryFunction
。
¥You can see that both of these types have all of the fields from the Character
Interface type, but also bring in extra fields—totalCredits
, starships
and primaryFunction
—that are specific to that particular type of character.
当你想要返回一个对象或一组对象时,接口类型很有用,但这些对象可能有几种不同的类型。例如,请注意以下查询会产生错误:
¥Interface types are useful when you want to return an object or set of objects, but those might be of several different types. For example, note that the following query produces an error:
hero
字段返回类型 Character
,这意味着它可能是 Human
或 Droid
,具体取决于 episode
参数。在上面的查询中,你只能询问 Character
接口类型上存在的字段,不包括 primaryFunction
。
¥The hero
field returns the type Character
, which means it might be either a Human
or a Droid
depending on the episode
argument. In the query above, you can only ask for fields that exist on the Character
Interface type, which doesn’t include primaryFunction
.
要请求特定对象类型的字段,你需要使用 内联片段:
¥To ask for a field on a specific Object type, you need to use an inline fragment:
接口类型也可以实现其他接口类型:
¥Interface types may also implement other Interface types:
interface Node {
id: ID!
}
interface Character implements Node {
id: ID!
name: String!
friends: [Character]
appearsIn: [Episode]!
}
请注意,接口类型可能无法实现自身或包含任何相互循环引用。
¥Note that Interface types may not implement themselves or contain any cyclic references to each other.
Character
is a useful abstraction for humans and droids.联合类型
¥Union types
GraphQL 支持第二种抽象类型,称为 联合类型。联合类型与接口类型有相似之处,但它们不能在组成类型之间定义任何共享字段。
¥GraphQL supports a second abstract type called a Union type. Union types share similarities with Interface types, but they cannot define any shared fields among the constituent types.
联合类型通过指示其成员对象类型来定义:
¥A Union type is defined by indicating its member Object types:
union SearchResult = Human | Droid | Starship
无论我们在结构中返回 SearchResult
类型,我们都可能得到 Human
、Droid
或 Starship
。请注意,联合类型的成员需要是具体的对象类型;你不能使用接口类型或其他联合类型作为成员来定义一个。
¥Wherever we return a SearchResult
type in our schema, we might get a Human
, a Droid
, or a Starship
. Note that members of a Union type need to be concrete Object types; you can’t define one using Interface types or other Union types as members.
在这种情况下,如果你查询返回 SearchResult
Union 类型的字段,则需要使用 内联片段 才能查询在成员 Object 类型上定义的任何字段:
¥In this case, if you query a field that returns the SearchResult
Union type, you need to use an inline fragment to be able to query any fields that are defined on the member Object types:
__typename
字段是一个特殊的元字段,它自动存在于每个对象类型上并解析为该类型的名称,从而提供一种区分客户端数据类型的方法。
¥The __typename
field is a special meta-field that automatically exists on every Object type and resolves to the name of that type, providing a way to differentiate between data types on the client.
此外,在这种情况下,由于 Human
和 Droid
共享一个公共接口 (Character
),你可以在一个地方查询它们的公共字段并仍然获得相同的结果:
¥Also, in this case, since Human
and Droid
share a common interface (Character
), you can query their common fields in one place and still get the same result:
请注意,name
仍然在 Starship
上指定,因为否则它不会显示在结果中,因为 Starship
不是 Character
!
¥Note that name
is still specified on Starship
because otherwise it wouldn’t show up in the results given that Starship
is not a Character
!
输入对象类型
¥Input Object types
我们在本页介绍的大多数示例都演示了对象、标量、枚举、接口和联合类型如何用作架构中字段的输出类型。但我们还看到字段参数必须指定它们的输入类型。
¥Most of the examples we’ve covered on this page demonstrate how Object, Scalar, Enum, Interface, and Union types may be used as output types for the fields in a schema. But we have also seen that field arguments must specify their input types.
到目前为止,我们仅讨论了使用标量值(如枚举或字符串类型)作为字段参数的输入类型。但是,你也可以使用 输入对象类型 将复杂对象作为参数传递,这是我们将要探索的最后一种 GraphQL 命名类型。
¥So far, we’ve only talked about using scalar values (like Enums or String types) as an input type for a field argument. However, you can also pass complex objects as arguments using an Input Object type, which is the last kind of named types in GraphQL that we’ll explore.
这在 mutations 的情况下尤其有价值,你可能希望传入要创建的整个对象。在 SDL 中,输入对象类型看起来类似于常规对象类型,但使用关键字 input
而不是 type
:
¥This is particularly valuable in the case of mutations, where you might want to pass in a whole object to be created. In SDL, Input Object types look similar to regular Object types, but with the keyword input
instead of type
:
input ReviewInput {
stars: Int!
commentary: String
}
type Mutation {
createReview(episode: Episode, review: ReviewInput!): Review
}
以下是如何在突变中使用输入对象类型:
¥Here is how you could use the Input Object type in a mutation:
输入对象类型上的字段可以引用其他输入对象类型,但你不能在架构中混合输入和输出类型。输入对象类型也不能在其字段上有参数。
¥The fields on an Input Object type can refer to other Input Object types, but you can’t mix input and output types in your schema. Input Object types also can’t have arguments on their fields.
指令
¥Directives
在字段参数不足或某些常见行为必须在多个位置复制的某些情况下,directives 允许我们使用 @
字符后跟指令的名称来修改 GraphQL 模式或操作的部分内容。
¥In certain instances where field arguments are insufficient or certain common behaviors must be replicated in multiple locations, directives allow us to modify parts of a GraphQL schema or operation by using an @
character followed by the directive’s name.
类型系统指令允许我们注释模式中的类型、字段和参数,以便可以以不同的方式验证或执行它们。
¥Type system directives allow us to annotate the types, fields, and arguments in a schema so that they may be validated or executed differently.
指令也可以定义为可执行指令以用于 GraphQL 操作。阅读有关查询页面上的可执行指令的更多信息。
¥Directives may also be defined for use in GraphQL operations as executable directives. Read more about executable directives on the Queries page.
GraphQL 规范定义了几个 内置指令。例如,对于支持 SDL 的实现,@deprecated
指令将可用于注释架构中已弃用的部分:
¥The GraphQL specification defines several built-in directives. For example, for implementations that support SDL, the @deprecated
directive will be available to annotate deprecated parts of the schema:
type User {
fullName: String
name: String @deprecated(reason: "Use `fullName`.")
}
虽然如果你使用的是支持 SDL 的 GraphQL 实现,则无需在架构中明确定义 @deprecated
指令,但其底层定义如下所示:
¥While you won’t need to define the @deprecated
directive in your schema explicitly if you’re using a GraphQL implementation that supports SDL, it’s underlying definition would look like this:
directive @deprecated(
reason: String = "No longer supported"
) on FIELD_DEFINITION | ENUM_VALUE
请注意,就像字段一样,指令可以接受参数,并且这些参数可以具有默认值。@deprecated
指令具有可空的 reason
参数,该参数接受 String
作为输入类型并回退到 "No longer supported"
。对于指令,我们必须指定它们可以在何处使用,例如在 @deprecated
指令的 FIELD_DEFINITION
或 ENUM_VALUE
上。
¥Note that, just like fields, directives can accept arguments and those arguments can have default values. The @deprecated
directive has a nullable reason
argument that accepts a String
as an input type and falls back to "No longer supported"
. And with directives, we must specify where they may be used, such as on a FIELD_DEFINITION
or ENUM_VALUE
for the @deprecated
directive.
除了 GraphQL 的内置指令外,你还可以定义自己的自定义指令。与自定义标量类型一样,由你选择的 GraphQL 实现决定如何在查询执行期间处理自定义指令。
¥In addition to GraphQL’s built-in directives, you may define your own custom directives. As with custom Scalar types, it’s up to your chosen GraphQL implementation to determine how to handle custom directives during query execution.
文档
¥Documentation
描述
¥Descriptions
GraphQL 允许你向架构中的类型、字段和参数添加文档。事实上,GraphQL 规范鼓励你在所有情况下都这样做,除非类型、字段或参数的名称是自描述的。架构描述使用 Markdown 语法定义,可以是多行或单行。
¥GraphQL allows you to add documentation to the types, fields, and arguments in a schema. In fact, the GraphQL specification encourages you to do this in all cases unless the name of the type, field, or argument is self-descriptive. Schema descriptions are defined using Markdown syntax and can be multiline or single line.
在 SDL 中,它们看起来像这样:
¥In SDL, they would look like this:
"""
A character from the Star Wars universe
"""
type Character {
"The name of the character."
name: String!
}
"""
The episodes in the Star Wars trilogy
"""
enum Episode {
"Star Wars Episode IV: A New Hope, released in 1977."
NEWHOPE
"Star Wars Episode V: The Empire Strikes Back, released in 1980."
EMPIRE
"Star Wars Episode VI: Return of the Jedi, released in 1983."
JEDI
}
"""
The query type, represents all of the entry points into our object graph
"""
type Query {
"""
Fetches the hero of a specified Star Wars film.
"""
hero(
"The name of the film that the hero appears in."
episode: Episode
): Character
}
除了使 GraphQL API 模式更具表现力之外,描述对客户端开发者也很有帮助,因为它们在 自省查询 中可用,并且在 GraphiQL 等开发者工具中可见。
¥In addition to making a GraphQL API schema more expressive, descriptions are helpful to client developers because they are available in introspection queries and visible in developer tools such as GraphiQL.
注释
¥Comments
有时,你可能需要在架构中添加注释,这些注释不描述类型、字段或参数,并且不打算让客户端看到。在这些情况下,你可以通过在文本前面加上 #
字符来向 SDL 添加单行注释:
¥Occasionally, you may need to add comments in a schema that do not describe types, fields, or arguments, and are not meant to be seen by clients. In those cases, you can add a single-line comment to SDL by preceding the text with a #
character:
# This line is treated like whitespace and ignored by GraphQL
type Character {
name: String!
}
还可以向客户端查询添加注释:
¥Comments may also be added to client queries:
后续步骤
¥Next steps
回顾我们学到的关于查询的知识:
¥To recap what we’ve learned about schemas and types:
-
根据选择哪个库来构建 GraphQL 服务,我们可以使用 SDL 以与语言无关的方式定义模式,或者通过从为其字段提供数据的代码中编译模式
¥Depending on what library is selected to build a GraphQL service, we can define a schema in a language-agnostic way using SDL or by compiling the schema from the code that provides data for its fields
-
GraphQL 中有六种命名类型定义:对象、标量、枚举、接口、联合和输入对象类型
¥There are six kinds of named type definitions in GraphQL: Object, Scalar, Enum, Interface, Union, and Input Object types
-
对象类型包含指定输出类型的字段,这些字段可能具有指定输入类型的参数
¥Object types contain fields that specify output types, and those fields may have arguments that specify input types
-
Int
、Float
、String
、Boolean
和ID
标量类型内置于 GraphQL 中,你也可以定义自己的自定义标量¥The
Int
,Float
,String
,Boolean
, andID
Scalar types are built into GraphQL, and you can also define your own custom scalars -
与标量类型一样,枚举类型表示 GraphQL 模式中的叶值,但它们仅限于一组有限的值
¥Like Scalar types, Enum types represent leaf values in a GraphQL schema but they are limited to a finite set of values
-
List (
[]
) 和非空 (!
) 类型修饰符允许你更改字段的输出类型或参数的输入类型的默认行为¥The List (
[]
) and Non-Null (!
) type modifiers allow you to change the default behavior for a field’s output type or argument’s input type -
接口和联合类型是抽象类型,允许从单个字段输出不同的具体对象类型
¥Interface and Union types are abstract types that allow different concrete Object types to be output from a single field
-
输入对象类型允许你将比标量和枚举类型允许的更复杂的值传递到字段参数或指令参数中
¥Input Object types allow you to pass more complex values into a field argument or directive argument than Scalar and Enum types allow
-
类型系统指令可以应用于模式中的类型、字段和参数,以改变它们在查询期间的验证和执行方式
¥Type system directives can be applied to the types, fields, and arguments in a schema to alter how they are validated and executed during a query
-
GraphQL 支持使用类型、字段和参数描述的模式文档,并且还支持被解析器忽略的注释
¥GraphQL supports schema documentation using type, field, and argument descriptions, and it also supports comments that are ignored by the parser
现在你了解了类型系统的主要功能,你已准备好了解有关如何 从 GraphQL API 查询数据 的更多信息。
¥Now that you understand the key features of the type system, you’re ready to learn more about how to query data from a GraphQL API.