

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

# 将 GraphQL 解析器组合在一起 AWS AppSync
<a name="tutorial-combining-graphql-resolvers-js"></a>

GraphQL 架构中的解析器和字段具有 1:1 的关系，具有很高的灵活性。由于数据来源是在解析器上独立于架构配置的，因此，您可以通过不同的数据来源解析或处理 GraphQL 类型，从而允许您混合使用和匹配架构以最佳方式满足您的需求。

以下场景说明了如何在架构中混合使用和匹配数据来源。在开始之前，您应该熟悉如何为 Amazon DynamoDB 和亚马逊 AWS Lambda服务配置数据源和解析器。 OpenSearch 

## 示例架构
<a name="example-schema-js"></a>

以下架构具有一个名为 `Post` 的类型，其中包含三个 `Query` 和 `Mutation` 操作：

```
type Post {
    id: ID!
    author: String!
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    version: Int!
}

type Query {
    allPost: [Post]
    getPost(id: ID!): Post
    searchPosts: [Post]
}

type Mutation {
    addPost(
        id: ID!,
        author: String!,
        title: String,
        content: String,
        url: String
    ): Post
    updatePost(
        id: ID!,
        author: String!,
        title: String,
        content: String,
        url: String,
        ups: Int!,
        downs: Int!,
        expectedVersion: Int!
    ): Post
    deletePost(id: ID!): Post
}
```

在该示例中，总共有 6 个解析器，每个解析器都需要一个数据来源。解决此问题的一种方法是将它们连接到`Posts`名为的单个 Amazon DynamoDB 表，在该`AllPost`表中，字段运行扫描，字段运行查询（参[JavaScript见 DynamoDB 的解析器函数参考](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html)）。`searchPosts`但是，您并不局限于亚马逊 DynamoDB；有不同的数据源（如 Lambda OpenSearch 或服务）可以满足您的业务需求。

## 通过解析器更改数据
<a name="alter-data-through-resolvers-js"></a>

您可能需要从 AWS AppSync 数据源不直接支持的第三方数据库返回结果。在将数据返回到 API 客户端之前，您可能还必须对数据执行复杂的修改。这可能是由于数据类型格式不正确造成的（例如，客户端上的时间戳差异），也可能是由于处理向后兼容性问题造成的。在这种情况下，将 AWS Lambda 函数作为数据源连接到您的 AWS AppSync API 是合适的解决方案。为了说明起见，在以下示例中， AWS Lambda 函数操作从第三方数据存储中获取的数据：

```
export const handler = (event, context, callback) => {
    // fetch data
    const result = fetcher()

    // apply complex business logic
    const data = transform(result)	

    // return to AppSync
    return data
};
```

这是一个完全有效的 Lambda 函数，可以附加到 GraphQL 架构中的 `AllPost` 字段，以便返回所有结果的任何查询都可以对顶/踩操作获得随机数字。

## DynamoDB 和服务 OpenSearch
<a name="ddb-and-es-js"></a>

对于某些应用程序，您可以对 DynamoDB 执行变更或简单查找查询，并让后台进程将文档传输到服务。 OpenSearch 您可以简单地将`searchPosts`解析器附加到 OpenSearch 服务数据源，然后使用 GraphQL 查询返回搜索结果（来自源自 DynamoDB 的数据）。在应用程序中添加高级搜索操作（例如关键字、模糊字词匹配，甚至地理空间查找）时，这可能是非常强大的。可以通过 ETL 流程完成从 DynamoDB 传输数据的过程，也可以使用 Lambda 从 DynamoDB 进行流式传输。

要开始使用这些特定数据来源，请参阅我们的 [DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-resolvers-js.html) 和 [Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers-js.html) 教程。

例如，通过使用以前教程中的架构，以下变更将一个项目添加到 DynamoDB 中：

```
mutation addPost {
  addPost(
    id: 123
    author: "Nadia"
    title: "Our first post!"
    content: "This is our first post."
    url: "https://aws.amazon.com/appsync/"
  ) {
    id
    author
    title
    content
    url
    ups
    downs
    version
  }
}
```

这会将数据写入 DynamoDB，然后 DynamoDB 通过 Lambda 将数据流式传输到 OpenSearch 亚马逊服务，然后您可以使用亚马逊服务按不同字段搜索帖子。例如，由于数据存储在 Amazon S OpenSearch ervice 中，因此您可以使用自由格式的文本（即使是空格）搜索作者字段或内容字段，如下所示：

```
query searchName{
    searchAuthor(name:"   Nadia   "){
        id
        title
        content
    }
}

---------- or ----------

query searchContent{
    searchContent(text:"test"){
        id
        title
        content
    }
}
```

由于数据直接写入到 DynamoDB 中，因此，您仍然可以使用 `allPost{...}` 和 `getPost{...}` 查询对表执行高效的列表或项目查找操作。该堆栈将以下示例代码用于 DynamoDB 流：

**注意**  
该 Python 代码是一个示例，并不适合在生产代码中使用。

```
import boto3
import requests
from requests_aws4auth import AWS4Auth

region = '' # e.g. us-east-1
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)

host = '' # the OpenSearch Service domain, e.g. https://search-mydomain.us-west-1.es.amazonaws.com
index = 'lambda-index'
datatype = '_doc'
url = host + '/' + index + '/' + datatype + '/'

headers = { "Content-Type": "application/json" }

def handler(event, context):
    count = 0
    for record in event['Records']:
        # Get the primary key for use as the OpenSearch ID
        id = record['dynamodb']['Keys']['id']['S']

        if record['eventName'] == 'REMOVE':
            r = requests.delete(url + id, auth=awsauth)
        else:
            document = record['dynamodb']['NewImage']
            r = requests.put(url + id, auth=awsauth, json=document, headers=headers)
        count += 1
    return str(count) + ' records processed.'
```

然后，您可以使用 DynamoDB 流将其附加到主键`id`为的 DynamoDB 表，并且对 DynamoDB 源的任何更改都将流式传输到您的服务域中。 OpenSearch 有关配置上述功能的更多信息，请参阅 [DynamoDB 流文档](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html)。