

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# GraphQL 的其他属性
<a name="graphql-properties"></a>

GraphQL 由多种设计原则组成，以在大规模系统中保持简单性和稳健性。

## 声明性
<a name="declarative-property"></a>

GraphQL 是声明性的，这意味着用户仅声明他们希望查询的字段以描述数据（设置形状）。响应仅返回这些属性的数据。例如，以下操作在 DynamoDB 表中检索 ISBN 13 值为的`Book`对象：`id`*9780199536061*

```
{
  getBook(id: "9780199536061") {
    name
    year
    author
  }
}
```

响应返回负载中的字段（`name`、`year` 和 `author`），而不返回任何其他内容：

```
{
  "data": {
    "getBook": {
      "name": "Anna Karenina",
      "year": "1878",
      "author": "Leo Tolstoy",
    }
  }
}
```

由于这种设计原则，GraphQL消除了REST在复杂系统中长期存在的过度吸引力和负担不足的问题。 APIs 这可以提高数据收集效率并提高网络性能。

## 分层
<a name="hierarchical-property"></a>

GraphQL 非常灵活，用户可以设置请求的数据形状以满足应用程序需求。请求的数据始终遵循 GraphQL API 中定义的属性的类型和语法。例如，以下代码段显示了使用名为的新字段范围的`getBook`操作`quotes`，该作用域返回所有存储的引号字符串和链接到的`Book`*9780199536061*页面：

```
{
  getBook(id: "9780199536061") {
    name
    year
    author
    quotes {
      description
      page
    }
  }
}
```

运行该查询将返回以下结果：

```
{
  "data": {
    "getBook": {
      "name": "Anna Karenina",
      "year": "1878",
      "author": "Leo Tolstoy",
      "quotes": [
         {
            "description": "The highest Petersburg society is essentially one: in it everyone knows everyone else, everyone even visits everyone else.",
            "page": 135
         },
         { 
            "description": "Happy families are all alike; every unhappy family is unhappy in its own way.",
            "page": 1
         },
         {        
            "description": "To Konstantin, the peasant was simply the chief partner in their common labor.",
            "page": 251
         }
      ]
    }
  }
}
```

正如您看到的一样，与请求的书籍关联的 `quotes` 字段以数组形式返回，其格式与查询描述的格式相同。尽管此处未显示，但 GraphQL 具有额外的优势，即不特别关注它检索的数据的位置。`Books` 和 `quotes` 可以是单独存储的，但只要存在关联，GraphQL 仍会检索该信息。这意味着，您的查询可以在单个请求中检索大量单独的数据。

## 内省
<a name="introspective-property"></a>

GraphQL 是自说明性的，或者说是内省的。它支持多种内置操作，以使用户能够查看架构中的基本类型和字段。例如，以下是具有 `date` 和 `description` 字段的 `Foo` 类型：

```
type Foo {
	date: String
	description: String
}
```

我们可以使用 `_type` 操作在架构下面查找类型元数据：

```
{
  __type(name: "Foo") {
    name                   # returns the name of the type
    fields {               # returns all fields in the type
      name                 # returns the name of each field
      type {               # returns all types for each field
        name               # returns the scalar type
      }
    }
  }
}
```

这会返回一个响应：

```
{
  "__type": {
    "name": "Foo",                     # The type name
    "fields": [
      {
        "name": "date",                # The date field
        "type": { "name": "String" }   # The date's type
      },
      {
        "name": "description",         # The description field
        "type": { "name": "String" }   # The description's type
      },
    ]
  }
}
```

该功能可用于找出特定 GraphQL 架构支持哪些类型和字段。GraphQL 支持各种这样的内省操作。有关更多信息，请参阅[内省](https://graphql.org/learn/introspection/)。

## 强类型
<a name="strong-typing-property"></a>

GraphQL 通过其类型和字段系统支持强类型。在架构中定义某些内容时，它必须具有可以在运行时之前验证的类型。它还必须遵循 GraphQL 的语法规范。这个概念与其他语言的编程没有什么不同。例如，以下是以前的 `Foo` 类型：

```
type Foo {
	date: String
	description: String
}
```

我们可以看到 `Foo` 是将创建的对象。在 `Foo` 实例中，具有一个 `date` 和 `description` 字段，它们都是 `String` 基元类型（标量）。从语法上讲，我们看到已声明 `Foo`，并且它的字段位于其范围内。这种类型检查和逻辑语法的组合确保您的 GraphQL API 简洁且不言自明。可以在[此处](https://spec.graphql.org/)找到 GraphQL 的类型和语法规范。