步骤 2:附加数据源 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

步骤 2:附加数据源

数据源是位于您的 Amazon 账户中并且 GraphQL API 可以与其交互的资源。AmazonAppSync 支持多种数据源,例如 Amazon Lambda、Amazon DynamoDB、关系数据库 (Amazon Aurora Serverless)、Amazon OpenSearch Service 和 HTTP 终端节点。Amazon AppSync API 可以配置为与多个数据源进行交互,以使您能够在单个位置中聚合数据。AmazonAppSync 可以使用您的账户中的现有 Amazon 资源,或代表您通过架构定义预置 DynamoDB 表。

以下几节说明了如何将数据源附加到 GraphQL API。

数据源类型

您现已在 Amazon AppSync 控制台中创建架构,您可以将数据源附加到该架构。在您最初创建 API 时,可以选择在创建预定义的架构期间预置 Amazon DynamoDB 表。不过,我们不会在本节中介绍该选项。您可以在启动架构一节中查看该选项的示例。

相反,我们介绍 Amazon AppSync 支持的所有数据源。在为您的应用程序选择正确的解决方案时,需要考虑很多因素。以下几节为每个数据源提供一些额外的上下文。有关数据源的一般信息,请参阅数据源

Amazon DynamoDB

Amazon DynamoDB 是用于可扩展的应用程序的 Amazon 主要存储解决方案之一。DynamoDB 的核心组件是,它就是一个数据集合。您通常会根据 BookAuthor 等实体创建表。表条目信息存储为项目,这些项目是每个条目的唯一字段组。完整项目表示数据库中的一行/一个记录。例如,Book 条目的项目可能包括 titleauthor 及其值。像 titleauthor 这样的单独字段称为属性,它们类似于关系数据库中的列值。

正如您猜测的一样,将使用表存储您的应用程序中的数据。Amazon AppSync 允许您将 DynamoDB 表挂载到 GraphQL API 以处理数据。请从前端 Web 和移动博客中获取该使用案例。该应用程序允许用户注册社交媒体应用程序。用户可以加入组,并上传文章以向订阅该组的其他用户广播。他们的应用程序将用户、文章和用户组信息存储在 DynamoDB 中。GraphQL API(由 Amazon AppSync 管理)与 DynamoDB 表进行交互。当用户在系统中进行更改并反映到前端时,GraphQL API 检索这些更改并向其他用户实时广播。

Amazon Lambda

Lambda 是一种事件驱动的服务,它自动构建所需的资源以运行代码,从而响应事件。Lambda 使用函数,这些函数是包含用于执行资源的代码、依赖项和配置的组语句。在函数检测到触发器(一组调用函数的活动)时,将自动执行函数。触发器可能是任意内容,例如进行 API 调用的应用程序、您的账户中启动资源的 Amazon 服务,等等。在触发时,函数将处理事件,这些事件是包含要修改的数据的 JSON 文档。

Lambda 非常适合运行代码,无需预置资源即可运行。请从前端 Web 和移动博客中获取该使用案例。该使用案例与 DynamoDB 一节中说明的使用案例有点相似。在该应用程序中,GraphQL API 负责定义操作,例如,添加文章(变更)和获取该数据(查询)。为了实施其操作的功能(例如 getPost ( id: String ! ) : PostgetPostsByAuthor ( author: String ! ) : [ Post ]),它们使用 Lambda 函数处理入站请求。在 Option 2: Amazon AppSync with Lambda resolver 下面,它们使用 Amazon AppSync 服务维护其架构,并将 Lambda 数据源链接到其中的一个操作。在调用该操作时,Lambda 与 Amazon RDS 代理交互以对数据库执行业务逻辑。

Amazon RDS

通过使用 Amazon RDS,您可以快速构建和配置关系数据库。在 Amazon RDS 中,您将创建一个通用数据库实例,以作为云中的隔离数据库环境。在该示例中,您使用一个数据库引擎,它是实际的 RDBMS 软件(PostgreSQL、MySQL 等)。该服务使用 Amazon 的基础设施和安全服务(如修补和加密)提供可扩展性,从而减少了大部分的后端工作并降低了部署的管理成本。

使用 Lambda 一节中的相同使用案例。在 Option 3: Amazon AppSync with Amazon RDS resolver 下面,提供的另一个选项是将 Amazon AppSync 中的 GraphQL API 直接链接到 Amazon RDS。通过使用数据 API,他们将数据库与 GraphQL API 相关联。一个解析器附加到字段(通常是查询、变更或订阅),并实施访问数据库所需的 SQL 语句。在客户端发出调用该字段的请求时,解析器执行这些语句并返回响应。

Amazon EventBridge

在 EventBridge 中,您将创建事件总线,它们是一些管道,用于从您附加的服务或应用程序(事件源)中接收事件,并根据一组规则处理事件。事件是执行环境中的某种状态变化,而规则是事件的一组筛选条件。规则遵循一种事件模式或事件状态变化元数据(ID、区域、账号、ARN 等)。在事件与事件模式匹配时,EventBridge 将事件通过管道发送到目标服务(目标),并触发规则中指定的操作。

EventBridge 适合将状态更改操作路由到某种其他服务。请从前端 Web 和移动博客中获取该使用案例。该示例介绍了一个电子商务解决方案,该解决方案具有多个团队以维护不同的服务。其中的一种服务在前端针对每个交付步骤(下订单、处理中、发货、交付等)向客户提供订单更新。不过,管理该服务的前端团队无法直接访问订购系统数据,因为该数据是由单独的后端团队维护的。后端团队的订购系统也被描述为黑匣子,因此,很难收集有关他们如何设置数据结构的信息。不过,后端团队确实设置了一个系统,以通过 EventBridge 管理的事件总线发布订单数据。为了访问来自该事件总线的数据并将其路由到前端,前端团队创建了一个新目标以指向 Amazon AppSync 中的 GraphQL API。他们还创建一条规则,以仅发送与订单更新相关的数据。在进行更新时,来自该事件总线的数据将发送到 GraphQL API。API 中的架构处理数据,然后将其传送到前端。

None 数据源

如果不打算使用数据源,您可以将其设置为 none。虽然 none 数据源仍明确归类为数据源,但并不是存储介质。通常,解析器在某一时刻调用一个或多个数据源以处理请求。不过,在某些情况下,您可能不需要处理数据源。如果将数据源设置为 none,将运行请求,跳过数据调用步骤,然后运行响应。

使用 EventBridge 一节中的相同使用案例。在架构中,变更处理状态更新,然后将其发送给订阅者。回想一下解析器的工作方式,通常至少调用一次数据源。不过,事件总线已自动发送本场景中的数据。这意味着变更不需要执行数据源调用;可以直接在本地处理订单状态。变更设置为 none,它充当传递值而不会调用数据源。然后,使用数据填充架构,该数据将发送给订阅者。

OpenSearch

Amazon OpenSearch Service 是一套用于实施全文搜索、数据可视化和日志记录的工具。可以使用该服务查询您上传的结构化数据。

在该服务中,您创建 OpenSearch 实例。这些实例称为节点。在节点中,您添加至少一个索引。从概念上讲,索引有点像关系数据库中的表。(不过,OpenSearch 不符合 ACID 标准,因此,不应以这种方式使用该服务)。您将使用上传到 OpenSearch Service 的数据填充索引。在上传您的数据时,将使用索引中存在的一个或多个分片对其编制索引。分片就像索引的一个分区,其中包含一些数据,并且可以与其他分片分开查询。在上传后,您的数据结构设置为称为文档的 JSON 文件。然后,您可以查询节点以获取文档中的数据。

HTTP 终端节点

您可以将 HTTP 终端节点作为数据源。AmazonAppSync 可以向终端节点发送具有参数和负载等相关信息的请求。将向解析器公开 HTTP 响应,解析器在完成操作后返回最终响应。

添加数据源

如果创建了数据源,您可以将其链接到 Amazon AppSync 服务,更具体地说,链接到 API。

Console
  1. 登录到 Amazon Web Services Management Console,然后打开 AppSync 控制台

    1. 控制面板中选择您的 API。

    2. 侧边栏中,选择数据源

  2. 选择创建数据源

    1. 命名您的数据源。您也可以为其提供描述,但这是可选的。

    2. 选择您的数据源类型

    3. 对于 DynamoDB,必须选择您的区域,然后选择该区域中的表。您可以选择创建新的通用表角色或导入表的现有角色,以规定与表交互的规则。您可以启用版本控制,在多个客户端同时尝试更新数据时,该功能可以自动为每个请求创建数据版本。版本控制用于保留和维护多个数据变体,以实现冲突检测和解决目的。您还可以启用自动架构生成功能,该功能获取您的数据源,并生成在架构中访问它所需的一些 CRUD、ListQuery 操作。

      对于 OpenSearch,必须选择您的区域,然后选择该区域中的域(集群)。您可以选择创建新的通用表角色或导入表的现有角色,以规定与域交互的规则。

      对于 Lambda,必须选择您的区域,然后选择该区域中的 Lambda 函数的 ARN。您可以选择创建新的通用表角色或导入表的现有角色,以规定与 Lambda 函数交互的规则。

      对于 HTTP,必须输入您的 HTTP 终端节点。

      对于 EventBridge,必须选择您的区域,然后选择该区域中的事件总线。您可以选择创建新的通用表角色或导入表的现有角色,以规定与事件总线交互的规则。

      对于 RDS,必须选择您的区域,然后选择密钥存储(用户名和密码)、数据库名称和架构。

      对于“None”,您将添加一个没有实际数据源的数据源。这是为了在本地处理解析器,而不是通过实际数据源。

      注意

      如果要导入现有的角色,它们需要使用信任策略。有关更多信息,请参阅 IAM 信任策略

  3. 选择创建

    注意

    或者,如果要创建 DynamoDB 数据源,您可以转到控制台中的架构页面,选择页面顶部的创建资源,然后填写一个预定义模型以转换为表。在该选项中,您填写或导入基本类型,配置包括分区键在内的基本表数据,并检查架构更改。

CLI
  • 运行 create-data-source 命令以创建数据源。

    您需要为该特定命令输入一些参数:

    1. 您的 API 的 api-id

    2. 您的表的 name

    3. 数据源的 type。根据您选择的数据源类型,您可能需要输入 service-role-arn-config 标签。

    示例命令可能如下所示:

    aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name data_source_name --type data_source_type --service-role-arn arn:aws:iam::107289374856:role/role_name --[data_source_type]-config {params}
CDK
提示

在使用 CDK 之前,我们建议您查看 CDK 的官方文档以及 Amazon AppSync 的 CDK 参考

下面列出的步骤仅显示用于添加特定资源的一般代码片段示例。这并不意味着,它是您的生产代码中的有效解决方案。我们还假设您已具有正常工作的应用程序。

要添加您的特定数据源,您需要将构造添加到堆栈文件中。可以在此处找到一个数据源类型列表:

  1. 一般来说,您可能需要将 import 指令添加到您使用的服务中。例如,它可能采用以下形式:

    import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service' import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'

    例如,这是您导入 Amazon AppSync 和 DynamoDB 服务的方法:

    import * as appsync from 'aws-cdk-lib/aws-appsync'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
  2. 某些服务(例如 RDS)要求在创建数据源之前在堆栈文件中进行一些额外的设置(例如,VPC 创建、角色和访问凭证)。有关更多信息,请参阅相关 CDK 页面中的示例。

  3. 对于大多数数据源(尤其是 Amazon 服务),您将在堆栈文件中创建新的数据源实例。通常,这会如下所示:

    const add_data_source_func = new service_scope.resource_name(scope: Construct, id: string, props: data_source_props);

    例如,以下是一个示例 Amazon DynamoDB 表:

    const add_ddb_table = new dynamodb.Table(this, 'Table_ID', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING, }, sortKey: { name: 'id', type: dynamodb.AttributeType.STRING, }, tableClass: dynamodb.TableClass.STANDARD, });
    注意

    大多数数据源至少具有一个必需的属性(使用 ? 符号表示)。请参阅 CDK 文档以了解需要使用哪些属性。

  4. 接下来,您需要将数据源链接到 GraphQL API。建议的方法是,在为管道解析器创建函数时添加数据源。例如,下面的代码片段是一个扫描 DynamoDB 表中的所有元素的函数:

    const add_func = new appsync.AppsyncFunction(this, 'func_ID', { name: 'func_name_in_console', add_api, dataSource: add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table), code: appsync.Code.fromInline(` export function request(ctx) { return { operation: 'Scan' }; } export function response(ctx) { return ctx.result.items; } `), runtime: appsync.FunctionRuntime.JS_1_0_0, });

    dataSource 属性中,您可以调用 GraphQL API (add_api),并使用其内置方法之一 (addDynamoDbDataSource) 在表和 GraphQL API 之间建立关联。参数是该链接在 Amazon AppSync 控制台中的名称(该示例中为 data_source_name_in_console)以及在表方法 (add_ddb_table) 中的名称。您在下一节中开始创建解析器,此时,将介绍有关该主题的更多信息。

    可以使用多种替代方法链接数据源。从技术上讲,您可以将 api 添加到表函数的属性列表中。例如,以下是步骤 3 中的代码片段,但具有包含 GraphQL API 的 api 属性:

    const add_api = new appsync.GraphqlApi(this, 'API_ID', { ... }); const add_ddb_table = new dynamodb.Table(this, 'Table_ID', { ... api: add_api });

    或者,您可以单独调用 GraphqlApi 构造:

    const add_api = new appsync.GraphqlApi(this, 'API_ID', { ... }); const add_ddb_table = new dynamodb.Table(this, 'Table_ID', { ... }); const link_data_source = add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table);

    我们建议仅在函数的属性中创建关联。否则,您必须在 Amazon AppSync 控制台中手动将解析器函数链接到数据源(如果要继续使用控制台值 data_source_name_in_console),或者在函数中使用另一个名称(例如 data_source_name_in_console_2)以创建单独的关联。这是由于属性处理信息的方式的限制造成的。

    注意

    您必须重新部署应用程序才能看到更改。

IAM 信任策略

如果您将现有的 IAM 角色用于数据源,则需要为该角色授予相应的权限,以对您的 Amazon 资源执行操作,例如对 Amazon DynamoDB 表执行 PutItem。您还需要修改该角色的信任策略,以允许 Amazon AppSync 使用该策略访问资源,如以下示例策略所示:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

您也可以根据需要在信任策略中添加条件,以限制对数据源的访问。目前,可以在这些条件中使用 SourceArnSourceAccount 键。例如,以下策略仅限账户 123456789012 访问数据源:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "aws:SourceAccount": "123456789012" } } } ] }

或者,您可以使用以下策略,仅限特定的 API(例如 abcdefghijklmnopq)访问数据源:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:appsync:us-west-2:123456789012:apis/abcdefghijklmnopq" } } } ] }

您可以使用以下策略,仅限特定区域(例如 us-east-1)中的所有 Amazon AppSync API 进行访问:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:appsync:us-east-1:123456789012:apis/*" } } } ] }

在下一节(配置解析器)中,我们将添加解析器业务逻辑,并将其附加到架构中的字段以处理数据源中的数据。

有关角色策略配置的更多信息,请参阅《IAM 用户指南》中的修改角色

有关适用于 Amazon AppSync 的 Amazon Lambda 解析器的跨账户访问的更多信息,请参阅 Building cross-account Amazon Lambda resolvers for Amazon AppSync