教程:组合使用 GraphQL 解析器 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

教程:组合使用 GraphQL 解析器

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

以下场景说明了如何在架构中混合使用和匹配数据源。在开始之前,您应该熟悉如何配置数据源以及 Amazon Lambda、Amazon DynamoDB 和 Amazon OpenSearch Service 的解析器。

示例架构

以下架构具有一个名为 Post 的类型,其中包含三个 QueryMutation 操作:

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 字段运行扫描,searchPosts 字段运行查询(请参阅 DynamoDB 的 JavaScript 解析器函数参考)。不过,您并不仅限于 Amazon DynamoDB;可以使用 Lambda 或 OpenSearch Service 等不同的数据源以满足您的业务要求。

通过解析器更改数据

您可能需要从 Amazon AppSync 数据源不直接支持的第三方数据库返回结果。在将数据返回到 API 客户端之前,您可能还必须对数据执行复杂的修改。这可能是由于数据类型格式不正确造成的(例如,客户端上的时间戳差异),也可能是由于处理向后兼容性问题造成的。在这种情况下,将 Amazon Lambda 函数作为数据源连接到 Amazon AppSync API 是合适的解决方案。出于说明目的,在以下示例中,Amazon 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 Service

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

要开始使用这些特定数据源,请参阅我们的 DynamoDBLambda 教程。

例如,通过使用以前教程中的架构,以下变更将一个项目添加到 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 将数据流式传输到 Amazon OpenSearch Service,您可以使用该服务按不同字段搜索文章。例如,由于数据位于 Amazon OpenSearch Service 中,您可以使用自由格式文本(甚至包含空格)搜索作者或内容字段,如下所示:

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 Service 域。有关配置上述功能的更多信息,请参阅 DynamoDB 流文档