教程:使用三种集成类型构建无服务器应用程序 - Amazon API Gateway
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

教程:使用三种集成类型构建无服务器应用程序

在本教程中,您使用 WebSocket API 创建一个无服务器广播应用程序。客户端可以接收消息,而无需轮询更新。

本教程介绍如何向连接的客户端广播消息,并包括 Lambda 授权方、模拟集成以及与 Step Functions 的非代理集成的示例。

使用 Amazon CloudFormation 模板创建资源后,您将使用 API Gateway 控制台来创建与 Amazon 资源集成的 WebSocket API。您需要将 Lambda 授权方附加到您的 API,并创建 Amazon 服务与 Step Functions 的集成,才能启动状态机执行。Step Functions 状态机将调用一个 Lambda 函数,来向所有连接的客户端发送消息。

构建 API 后,您将测试到 API 的连接,并验证消息是否已发送和接收。完成本教程需要大约 45 分钟。

先决条件

您需要以下先决条件:

我们建议您在开始本教程之前,完成 WebSocket 聊天应用程序教程。要完成 WebSocket 聊天应用程序教程,请参阅教程:使用 WebSocket API、Lambda 和 DynamoDB 构建无服务器聊天应用程序

步骤 1:创建资源

下载并解压缩适用于 Amazon CloudFormation 的应用程序创建模板。您将使用此模板创建以下各项:

  • 处理 API 请求并授权访问您的 API 的 Lambda 函数。

  • 用于存储客户端 ID 和由 Lambda 授权方返回的主体用户标识的 DynamoDB 表。

  • 用于向连接的客户端发送消息的 Step Functions 状态机。

创建 Amazon CloudFormation 堆栈
  1. 打开 Amazon CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation

  2. 选择创建堆栈,然后选择使用新资源(标准)

  3. 对于指定模板,选择上传模板文件

  4. 选择您下载的模板。

  5. 选择下一步

  6. 对于堆栈名称,输入 websocket-step-functions-tutorial,然后选择下一步

  7. 对于配置堆栈选项,请选择下一步

  8. 对于功能,请确认 Amazon CloudFormation 可以在您的账户中创建 IAM 资源。

  9. 选择提交

Amazon CloudFormation 预置在模板中指定的资源。完成资源预置可能需要几分钟时间。选择输出选项卡,来查看您创建的资源及其 ARN。当 Amazon CloudFormation 堆栈的状态为 CREATE_COMPLETE 时,您就可以继续下一步了。

步骤 2:创建 WebSocket API

您将创建一个 WebSocket API 来处理客户端连接,并将请求路由到您在步骤 1 中创建的资源。

创建 WebSocket API
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. 选择创建 API。对于 WebSocket API,选择构建

  3. 对于 API 名称,请输入 websocket-step-functions-tutorial

  4. 对于路由选择表达式,输入 request.body.action

    路由选择表达式确定当客户端发送消息时 API Gateway 调用的路由。

  5. 选择下一步

  6. 对于预定义路由,选择添加 $connect添加 $disconnect添加 $default

    $connect$disconnect 路由是 API Gateway 在客户端连接到 API 或断开与 API 的连接时自动调用的特殊路由。当没有其它路由与请求匹配时,API Gateway 调用 $default 路由。创建 API 后,您将创建一个连接到 Step Functions 的自定义路由。

  7. 选择下一步

  8. 对于 $connect 的集成,请执行以下操作:

    1. 对于集成类型,选择 Lambda

    2. 对于 Lambda 函数,选择您在步骤 1 中使用 Amazon CloudFormation 创建的相应 $connect Lambda 函数。Lambda 函数名称应该以 websocket-step 开头。

  9. 对于 $disconnect 的集成,请执行以下操作:

    1. 对于集成类型,选择 Lambda

    2. 对于 Lambda 函数,选择您在步骤 1 中使用 Amazon CloudFormation 创建的相应 $disconnect Lambda 函数。Lambda 函数名称应该以 websocket-step 开头。

  10. 对于 $default 的集成,请选择模拟

    在模拟集成中,API Gateway 在没有集成后端的情况下管理路由响应。

  11. 选择下一步

  12. 查看 API Gateway 为您创建的阶段。默认情况下,API Gateway 会创建名为生产的阶段,然后自动将您的 API 部署到该阶段。选择下一步

  13. 选择创建和部署

步骤 3:创建 Lambda 授权方

要控制对您的 WebSocket API 的访问权限,您需要创建 Lambda 授权方。Amazon CloudFormation 模板为您创建了 Lambda 授权方函数。您可以在 Lambda 控制台中看到 Lambda 函数。名称应以 websocket-step-functions-tutorial-AuthorizerHandler 开头。除非 Authorization 标头是 Allow,否则此 Lambda 函数会拒绝对 WebSocket API 的所有调用。Lambda 函数还会将 $context.authorizer.principalId 变量传递给您的 API,稍后会在 DynamoDB 表中使用该变量来标识 API 调用方。

在此步骤中,您将配置 $connect 路由来使用 Lambda 授权方。

创建 Lambda 授权方
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. 在主导航窗格中,选择授权方

  3. 选择创建授权方

  4. 对于授权方名称,输入 LambdaAuthorizer

  5. 对于授权方 ARN,输入由 Amazon CloudFormation 模板创建的授权方的名称。名称应以 websocket-step-functions-tutorial-AuthorizerHandler 开头。

    注意

    我们建议不要为生产 API 使用此示例授权方。

  6. 对于身份来源类型,选择标头。对于,输入 Authorization

  7. 选择创建授权方

创建授权方后,将其附加到您的 API 的 $connect 路由。

将授权方附加到 $connect 路由
  1. 在主导航窗格中,选择路由

  2. 选择 $connect 路由。

  3. 路由请求设置部分中,选择编辑

  4. 对于授权,请选择下拉菜单,然后选择您的请求授权方。

  5. 选择保存更改

步骤 4:创建模拟双向集成

接下来,您将为 $default 路由创建双向模拟集成。模拟集成可让您在不使用后端的情况下向客户端发送响应。当您为 $default 路由创建集成时,您可以向客户端展示如何与 API 进行交互。

您可以配置 $default 路由来通知客户端使用 sendmessage 路由。

创建模拟请求
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. 选择 $default 路由,然后选择集成请求选项卡。

  3. 对于请求模板,请选择编辑

  4. 对于模板选择表达式,输入 200,然后选择编辑

  5. 集成请求选项卡上,对于请求模板,选择创建模板

  6. 对于模板密钥,输入 200

  7. 对于生成模板,输入以下映射模板:

    {"statusCode": 200}

    选择创建模板

    结果应该类似以下内容:

  8. $default 路由窗格中,选择启用双向通信

  9. 选择集成响应选项卡,然后选择创建集成响应

  10. 对于响应密钥,输入 $default

  11. 对于模板选择表达式,输入 200

  12. 选择创建响应

  13. 响应模板下,选择创建模板

  14. 对于模板密钥,输入 200

  15. 对于响应模板,输入以下映射模板:

    {"Use the sendmessage route to send a message. Connection ID: $context.connectionId"}
  16. 选择创建模板

    结果应该类似以下内容:

步骤 5:使用 Step Functions 创建非代理集成

接下来,创建 sendmessage 路由。客户端可以调用 sendmessage 路由,来向所有连接的客户端广播消息。sendmessage 路由已将非代理 Amazon 服务与 Amazon Step Functions 集成。该集成会针对 Amazon CloudFormation 模板为您创建的 Step Functions 状态机调用 StartExecution 命令。

创建非代理集成
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. 选择创建路由

  3. 对于路由键,请输入 sendmessage

  4. 对于集成类型,选择 Amazon 服务

  5. 对于 Amazon 区域,输入您部署了 Amazon CloudFormation 模板的区域。

  6. 对于 Amazon 服务,选择 Step Functions

  7. 对于 HTTP 方法,选择 POST

  8. 对于操作名称,输入 StartExecution

  9. 对于执行角色,输入由 Amazon CloudFormation 模板创建的执行角色。名称应为 WebsocketTutorialApiRole

  10. 选择创建路由

接下来,您创建一个映射模板,来将请求参数发送到 Step Functions 状态机。

创建映射模板
  1. 选择 sendmessage 路由,然后选择集成请求选项卡。

  2. 请求模板部分中,选择编辑

  3. 对于模板选择表达式,输入 \$default

  4. 选择编辑

  5. 请求模板部分,选择创建模板

  6. 对于模板密钥,输入 \$default

  7. 对于生成模板,输入以下映射模板:

    #set($domain = "$context.domainName") #set($stage = "$context.stage") #set($body = $input.json('$')) #set($getMessage = $util.parseJson($body)) #set($mymessage = $getMessage.message) { "input": "{\"domain\": \"$domain\", \"stage\": \"$stage\", \"message\": \"$mymessage\"}", "stateMachineArn": "arn:aws:states:us-east-2:123456789012:stateMachine:WebSocket-Tutorial-StateMachine" }

    stateMachineArn 替换为由 Amazon CloudFormation 创建的状态机的 ARN。

    映射模板执行以下操作:

    • 使用上下文变量 domainName 创建变量 $domain

    • 使用上下文变量 stage 创建变量 $stage

      $domain$stage 变量是构建回调 URL 所必需的。

    • 接收传入的 sendmessage JSON 消息,并提取 message 属性。

    • 为状态机创建输入。输入是 WebSocket API 的域和阶段以及来自 sendmessage 路由的消息。

  8. 选择创建模板

您可以在 $connect$disconnect 路由上创建非代理集成,来直接在 DynamoDB 表中添加或移除连接 ID,而无需调用 Lambda 函数。

步骤 6:测试您的 API

接下来,您将部署和测试您的 API 来确保它正常工作。您将使用 wscat 命令连接到 API,然后,您将使用斜杠命令发送 ping 帧来检查与 WebSocket API 的连接。

部署 API
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. 在主导航窗格中,选择路由

  3. 选择部署 API

  4. 对于阶段,选择生产

  5. (可选)对于部署描述,输入描述。

  6. 选择部署

部署 API 后,您可以调用它。使用调用 URL 来调用您的 API。

获取您的 API 的调用 URL
  1. 选择 API。

  2. 选择阶段,然后选择生产

  3. 记下 API 的 WebSocket URL。该 URL 应类似于 wss://abcdef123.execute-api.us-east-2.amazonaws.com/production

现在您已经有了调用 URL,您可以测试与 WebSocket API 的连接了。

测试与您的 API 的连接
  1. 使用以下命令连接到您的 API。首先,通过调用 /ping 路径来测试连接。

    wscat -c wss://abcdef123.execute-api.us-east-2.amazonaws.com/production -H "Authorization: Allow" --slash -P
    Connected (press CTRL+C to quit)
  2. 输入以下命令来 ping 控制帧。您可以从客户端使用控制帧来实现保持活动目的。

    /ping

    结果应该类似以下内容:

    < Received pong (data: "")

现在您已经测试了连接,您可以测试 API 是否正常工作。在此步骤中,您打开一个新的终端窗口,以便 WebSocket API 可以向所有连接的客户端发送消息。

要测试您的 API
  1. 打开一个新终端并使用以下参数再次运行 wscat 命令。

    wscat -c wss://abcdef123.execute-api.us-east-2.amazonaws.com/production -H "Authorization: Allow"
    Connected (press CTRL+C to quit)
  2. API Gateway 根据 API 的路由请求选择表达式确定要调用的路由。您的 API 的路由选择表达式是 $request.body.action。因此,当您发送以下消息时,API Gateway 会调用 sendmessage 路由:

    {"action": "sendmessage", "message": "hello, from Step Functions!"}

    与路由关联的 Step Functions 状态机使用消息和回调 URL 调用 Lambda 函数。Lambda 函数调用 API Gateway 管理 API,并将消息发送给所有连接的客户端。所有客户端都会收到以下消息:

    < hello, from Step Functions!

现在您已经测试了 WebSocket API,可以断开与 API 的连接。

从 API 断开连接
  • CTRL+C 以从 API 断开连接。

    当客户端与 API 断开连接时,API Gateway 会调用 API 的 $disconnect 路由。适用于 API 的 $disconnect 路由的 Lambda 集成会从 DynamoDB 中删除连接 ID。

步骤 7:清除

为避免不必要的成本,请删除作为本教程的一部分而创建的资源。以下步骤将删除您的 Amazon CloudFormation 堆栈和 WebSocket API。

删除 WebSocket API
  1. 通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway

  2. API 页面上,选择您的 websocket-api

  3. 选择操作,选择删除,然后确认您的选择。

删除 Amazon CloudFormation 堆栈
  1. 打开 Amazon CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation

  2. 选择您的 Amazon CloudFormation 堆栈。

  3. 选择删除,然后确认您的选择。

后续步骤

您可以自动创建和清理本教程中涉及的所有 Amazon 资源。有关本教程中自动执行这些操作的 Amazon CloudFormation 模板的示例,请参阅 ws-sfn.zip