

 [适用于 JavaScript 的 AWS SDK V3 API 参考指南](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)详细描述了 适用于 JavaScript 的 AWS SDK 版本 3 (V3) 的所有 API 操作。

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

# 使用 API Gateway 调用 Lambda
<a name="api-gateway-invoking-lambda-example"></a>

您可以使用 Amazon API Gateway 调用 Lambda 函数，该 AWS 服务用于大规模创建、发布、维护、监控和保护 REST、HTTP。 WebSocket APIs API 开发人员可以创建 APIs 该访问权限 AWS 或其他网络服务，以及存储在 AWS 云端的数据。作为 API Gateway 开发者，您可以创建 APIs 用于自己的客户端应用程序。有关更多信息，请参阅[什么是 Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)。

AWS Lambda 是一项计算服务，使您无需预置或管理服务器即可运行代码。您可以使用各种编程语言创建 Lambda 函数。有关的更多信息 AWS Lambda，请参阅[什么是 AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)。

在此示例中，您将使用 Lambda 运行时 API 创建一个 Lambda 函数。 JavaScript 此示例调用不同的 AWS 服务来执行特定的用例。例如，假设组织在员工入职一周年纪念日时向员工发送移动短信表示祝贺，如下图所示。

![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picPhone.png)


完成此示例大约需要 20 分钟。

此示例向您展示如何使用 JavaScript 逻辑来创建执行此用例的解决方案。例如，您将学习如何使用 Lambda 函数读取数据库以确定哪些员工已达到入职一周年纪念日、如何处理数据以及如何发送短信。然后，您将学习如何使用 API Gateway 通过 Rest 端点调用此 AWS Lambda 函数。例如，您可以使用以下 curl 命令调用 Lambda 函数：

```
curl -XGET "https://xxxxqjko1o3.execute-api.us-east-1.amazonaws.com/cronstage/employee" 
```

本 AWS 教程使用名为 Employee 的 Amazon DynamoDB 表，其中包含这些字段。
+ **id** - 表的主键。
+ **firstName** - 员工的名字。
+ **phone** - 员工的电话号码。
+ **startDate** - 员工的入职日期。

![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/pic00.png)


**重要**  
完成费用：本文档中包含的 AWS 服务包含在 AWS 免费套餐中。但是，请务必在完成此示例后终止所有资源，以确保系统不会向您收费。

**构建应用程序：**

1. [满足先决条件](#api-gateway-invoking-lambda-provision-resources)

1. [创建 AWS 资源](#api-gateway-invoking-lambda-provision-resources)

1. [准备浏览器脚本](#api-gateway-invoking-lambda-browser-script)

1. [创建并上传 Lambda 函数](#api-gateway-invoking-lambda-browser-script)

1. [部署 Lambda 函数](#api-gateway-invoking-lambda-deploy-function)

1. [运行应用程序](#api-gateway-invoking-lambda-run)

1. [删除资源](#api-gateway-invoking-lambda-destroy)

## 完成先决条件任务
<a name="api-gateway-invoking-lambda-prerequisites"></a>

要设置和运行此示例，您必须先完成以下任务：
+ 设置项目环境以运行这些 Node TypeScript 示例，并安装所需的模块 适用于 JavaScript 的 AWS SDK 和第三方模块。按照上的说明进行操作[ GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/cross-services/lambda-api-gateway/README.md)。
+ 使用用户凭证创建共享配置文件。有关提供共享凭据文件的更多信息，请参阅[和*工具参考指南中的共享配置AWS SDKs 和*凭据文件](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)。

## 创建 AWS 资源
<a name="api-gateway-invoking-lambda-provision-resources"></a>

本教程要求具有以下资源:
+ 一个名为 `Employee` 的 Amazon DynamoDB 表，其键名为 `Id`，其字段如上图所示。请务必输入正确的数据，包括要用来测试此使用案例的有效手机号。有关更多信息，请参阅[创建表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html)。
+ 具有执行 Lambda 函数的附加权限的 IAM 角色。
+ 一个用于托管 Lambda 函数的 Amazon S3 存储桶。

您可以手动创建这些资源，但我们建议 CloudFormation 按照本教程中的说明使用配置这些资源。

### 使用创建 AWS 资源 CloudFormation
<a name="api-gateway-invoking-lambda-resources-cli"></a>

CloudFormation 使您能够以可预测的方式重复创建和配置 AWS 基础架构部署。有关的更多信息 CloudFormation，请参阅《[AWS CloudFormation 用户指南》](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/)。

要使用以下方法创建 CloudFormation 堆栈 AWS CLI：

1. 按照《 AWS CLI [AWS CLI 用户指南](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)》中的说明进行安装和配置。

1. 在项目文件夹的根目录`setup.yaml`中创建一个名为的文件，然后将[此处](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/setup.yaml)的内容复制 GitHub到该文件中。
**注意**  
该 CloudFormation 模板是使用[此处 AWS CDK 提供的模板生成的 GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/resources/cdk/lambda_using_api_gateway)。有关更多信息 AWS CDK，请参阅《[AWS Cloud Development Kit (AWS CDK) 开发人员指南》](https://docs.aws.amazon.com/cdk/latest/guide/)。

1. 从命令行运行以下命令，*STACK\$1NAME*替换为堆栈的唯一名称。
**重要**  
堆栈名称在 AWS 区域和 AWS 账户中必须是唯一的。您最多可指定 128 个字符，支持数字和连字符。

   ```
   aws cloudformation create-stack --stack-name STACK_NAME --template-body file://setup.yaml --capabilities CAPABILITY_IAM
   ```

   有关 `create-stack` 命令参数的更多信息，请参阅 [AWS CLI 命令参考指南](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html)和 [CloudFormation 用户指南](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-cli-creating-stack.html)。

1. 接下来，按照[填充表](#api-gateway-invoking-lambda-resources-create-table)过程填充表。

### 填充表
<a name="api-gateway-invoking-lambda-resources-create-table"></a>

要填充表，请先创建一个名为 `libs` 的目录，然后在其中创建一个名为 `dynamoClient.js` 的文件，再将下面的内容粘贴到其中。

```
const { DynamoDBClient } = require ( "@aws-sdk/client-dynamodb" );
// Set the AWS Region.
const REGION = "REGION"; // e.g. "us-east-1"
 // Create an Amazon Lambda service client object.
const dynamoClient = new DynamoDBClient({region:REGION});
module.exports = { dynamoClient };
```

 此代码可从[此处获](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/libs/dynamoClient.js)得 GitHub。

接下来，在项目文件夹的根目录`populate-table.js`中创建一个名为的文件，并将[此处](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/helper-functions/populate-table.js)的内容复制 GitHub到该文件中。对于其中一项，将 `phone` 属性的值替换为 E.164 格式的有效手机号码，将 `startDate` 的值替换为今天的日期。

在命令行处，运行以下命令。

```
node populate-table.js
```

```
const { BatchWriteItemCommand } = require ( "aws-sdk/client-dynamodb" );
const {dynamoClient} = require ( "./libs/dynamoClient" );

// Set the parameters.
export const params = {
  RequestItems: {
    Employees: [
      {
        PutRequest: {
          Item: {
            id: { N: "1" },
            firstName: { S: "Bob" },
            phone: { N: "155555555555654" },
            startDate: { S: "2019-12-20" },
          },
        },
      },
      {
        PutRequest: {
          Item: {
            id: { N: "2" },
            firstName: { S: "Xing" },
            phone: { N: "155555555555653" },
            startDate: { S: "2019-12-17" },
          },
        },
      },
      {
        PutRequest: {
          Item: {
            id: { N: "55" },
            firstName: { S: "Harriette" },
            phone: { N: "155555555555652" },
            startDate: { S: "2019-12-19" },
          },
        },
      },
    ],
  },
};

export const run = async () => {
  try {
    const data = await dbclient.send(new BatchWriteItemCommand(params));
    console.log("Success", data);
  } catch (err) {
    console.log("Error", err);
  }
};
run();
```

 此代码可从[此处获](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/helper-functions/populate-table.js)得 GitHub。

## 创建 AWS Lambda 函数
<a name="api-gateway-invoking-lambda-browser-script"></a>

### 配置 SDK
<a name="api-gateway-invoking-lambda-configure-sdk"></a>

在 `libs` 目录中，创建名为 `snsClient.js` 和 `lambdaClient.js` 的文件，并将以下内容分别粘贴到这些文件中。

```
const { SNSClient } = require("@aws-sdk/client-sns");
// Set the AWS Region.
const REGION = "REGION"; //e.g. "us-east-1"
// Create an Amazon SNS service client object.
const snsClient = new SNSClient({ region: REGION });
module.exports = { snsClient };
```

 *REGION*替换为 AWS 区域。此代码可从[此处获](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/libs/snsClient.js)得 GitHub。

```
const { LambdaClient } = require("@aws-sdk/client-lambda");
// Set the AWS Region.
const REGION = "REGION"; //e.g. "us-east-1"
// Create an Amazon Lambda service client object.
const lambdaClient = new LambdaClient({ region: REGION });
module.exports = { lambdaClient };
```

*REGION*替换为 AWS 区域。此代码可从[此处获](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/libs/lambdaClient.js)得 GitHub。

首先，导入所需的 适用于 JavaScript 的 AWS SDK (v3) 模块和命令。然后计算今天的日期并将其分配给一个参数。然后，为 `ScanCommand` 创建参数。*TABLE\$1NAME*替换为您在本示例[创建 AWS 资源](#api-gateway-invoking-lambda-provision-resources)部分中创建的表的名称。

下面的代码段演示了此步骤。（有关完整示例，请参阅[捆绑 Lambda 函数](#api-gateway-invoking-lambda-full)。）

```
const { ScanCommand } = require("@aws-sdk/client-dynamodb");
const { PublishCommand } = require("@aws-sdk/client-sns");
const { snsClient } = require("./libs/snsClient");
const { dynamoClient } = require("./libs/dynamoClient");

// Get today's date.
const today = new Date();
const dd = String(today.getDate()).padStart(2, "0");
const mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0!
const yyyy = today.getFullYear();
const date = `${yyyy}-${mm}-${dd}`;

// Set the parameters for the ScanCommand method.
const params = {
  // Specify which items in the results are returned.
  FilterExpression: "startDate = :topic",
  // Define the expression attribute value, which are substitutes for the values you want to compare.
  ExpressionAttributeValues: {
    ":topic": { S: date },
  },
  // Set the projection expression, which are the attributes that you want.
  ProjectionExpression: "firstName, phone",
  TableName: "Employees",
};
```

### 扫描 DynamoDB 表
<a name="api-gateway-invoking-lambda-scan-table"></a>

首先，创建一个名为的 async/await 函数`sendText`，用于使用 Amazon SNS `PublishCommand` 发布一条短信。然后，添加一个 `try` 块模式，用于扫描 DynamoDB 表中是否有工作周年纪念日在今天的员工，然后调用 `sendText` 函数向这些员工发送短信。如果发生错误，则将调用 `catch` 块。

下面的代码段演示了此步骤。（有关完整示例，请参阅[捆绑 Lambda 函数](#api-gateway-invoking-lambda-full)。）

```
// Helper function to send message using Amazon SNS.
exports.handler = async () => {
  // Helper function to send message using Amazon SNS.
  async function sendText(textParams) {
    try {
      await snsClient.send(new PublishCommand(textParams));
      console.log("Message sent");
    } catch (err) {
      console.log("Error, message not sent ", err);
    }
  }
  try {
    // Scan the table to identify employees with work anniversary today.
    const data = await dynamoClient.send(new ScanCommand(params));
    for (const element of data.Items) {
      const textParams = {
        PhoneNumber: element.phone.N,
        Message: `Hi ${element.firstName.S}; congratulations on your work anniversary!`,
      };
      // Send message using Amazon SNS.
      sendText(textParams);
    }
  } catch (err) {
    console.log("Error, could not scan table ", err);
  }
};
```

### 捆绑 Lambda 函数
<a name="api-gateway-invoking-lambda-full"></a>

本主题介绍如何将本示例的模块`mylambdafunction.ts`和必需的 适用于 JavaScript 的 AWS SDK 模块捆绑到名`index.js`为的捆绑文件中。

1. 如果您尚未安装 Webpack，请按照本示例中的[完成先决条件任务](#api-gateway-invoking-lambda-prerequisites)部分进行安装。
**注意**  
有关 *Webpack* 的信息，请参阅[使用 Webpack 捆绑应用程序](webpack.md)。

1. 在命令行中运行以下命令，将本示例 JavaScript 的捆绑到名为的文件中`<index.js>`：

   ```
   webpack mylambdafunction.ts --mode development --target node --devtool false --output-library-target umd -o index.js
   ```
**重要**  
请注意，输出被命名为 `index.js`。这是因为 Lambda 函数必须有一个 `index.js` 处理程序才能工作。

1. 将捆绑的输出文件 `index.js` 压缩到名为 `mylambdafunction.zip` 的 ZIP 文件中。

1. 将 `mylambdafunction.zip` 上传到您在本教程的[创建 AWS 资源](#api-gateway-invoking-lambda-provision-resources)主题中创建的 Amazon S3 存储桶。

## 部署 Lambda 函数
<a name="api-gateway-invoking-lambda-deploy-function"></a>

在项目的根目录中，创建一个 `lambda-function-setup.ts` 文件，然后将以下内容粘贴到其中。

*BUCKET\$1NAME*替换为您将 Lambda 函数的 ZIP 版本上传到的 Amazon S3 存储桶的名称。将 *ZIP\$1FILE\$1NAME* Lambda 函数的 ZIP 版本替换为命名的名称。*ROLE*替换为您在本教程[创建 AWS 资源](#api-gateway-invoking-lambda-provision-resources)主题中创建的 IAM 角色的 Amazon 资源编号 (ARN)。*LAMBDA\$1FUNCTION\$1NAME*替换为 Lambda 函数的名称。

```
// Load the required Lambda client and commands.
const {
  CreateFunctionCommand
} = require ( "@aws-sdk/client-lambda" );
const { lambdaClient} = require ( "./libs/lambdaClient.js );

// Set the parameters.
const params = {
  Code: {
    S3Bucket: "BUCKET_NAME", // BUCKET_NAME
    S3Key: "ZIP_FILE_NAME", // ZIP_FILE_NAME
  },
  FunctionName: "LAMBDA_FUNCTION_NAME",
  Handler: "index.handler",
  Role: "IAM_ROLE_ARN", // IAM_ROLE_ARN; e.g., arn:aws:iam::650138640062:role/v3-lambda-tutorial-lambda-role
  Runtime: "nodejs12.x",
  Description:
    "Scans a DynamoDB table of employee details and using Amazon Simple Notification Services (Amazon SNS) to " +
    "send employees an email on each anniversary of their start-date.",
};

const run = async () => {
  try {
    const data = await lambdaClient.send(new CreateFunctionCommand(params));
    console.log("Success", data); // successful response
  } catch (err) {
    console.log("Error", err); // an error occurred
  }
};
run();
```

在命令行中输入以下内容以部署 Lambda 函数。

```
node lambda-function-setup.ts
```

此代码示例可在此[处找到 GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cross-services/lambda-api-gateway/src/helper-functions/lambda-function-setup.js)。

## 配置 API Gateway 以调用 Lambda 函数
<a name="api-gateway-invoking-lambda-run"></a>

**构建应用程序：**

1. [创建 rest API](#api-gateway-invoking-lambda-run-create)

1. [测试 API Gateway 方法](#api-gateway-invoking-lambda-run-test)

1. [部署 API Gateway 方法](#api-gateway-invoking-lambda-run-deploy)

### 创建 rest API
<a name="api-gateway-invoking-lambda-run-create"></a>

您可以使用 API Gateway 控制台为 Lambda 函数创建 rest 端点。完成后，您就可以使用 restful 调用来调用 Lambda 函数。



1. 登录 [Amazon API Gateway 控制台](https://console.aws.amazon.com/apigateway)。

1. 在 Rest API 下，选择**生成**。

1. 选择**新建 API**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/PicNewAPI.png)

1. 指定 **Employee** 作为 API 名称并提供描述。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picEmployeeAPI.png)

1. 选择**创建 API**。

1. 在 **Employee** 部分下选择**资源**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picResources.png)

1. 在名称字段中，指定**员工**。

1. 选择**创建资源**。

1. 从**操作**下拉菜单中，选择**创建资源**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picCreateResources.png)

1. 选择 **/employees**，从**操作**中选择**创建方法**，然后从 **/employees** 下的下拉菜单中选择 **GET**。选择复选标记图标。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picGet.png)

1. 选择 **Lambda 函数**并输入 m**mylambdafunction** 作为 Lambda 函数名称。选择**保存**。

### 测试 API Gateway 方法
<a name="api-gateway-invoking-lambda-run-test"></a>

在本教程中，您可以测试调用 **mylambdafunction** Lambda 函数的 API Gateway 方法。要测试该方法，请选择**测试**，如下图所示。

![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picTest.png)


调用 Lambda 函数后，您可以查看日志文件以查看成功消息。

### 部署 API Gateway 方法
<a name="api-gateway-invoking-lambda-run-deploy"></a>

测试成功后，您可以从 [Amazon API Gateway 控制台](https://console.aws.amazon.com/apigateway)部署该方法。

1. 选择 **GET**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picGetDeploy.png)

1. 从**操作**下拉列表中，选择**部署 API**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picDeployMethod.png)

1. 填写**部署 API** 表单，然后选择**部署**。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picDeployMethod.png)

1.  选择**保存更改**。

1.  再次选择 **GET**，可以看到 URL 已更改。这是您可以用来调用 Lambda 函数的调用 URL。  
![\[DynamoDB 表\]](http://docs.aws.amazon.com/zh_cn/sdk-for-javascript/v3/developer-guide/images/apigateway_example/picURL2.png)

## 删除资源
<a name="api-gateway-invoking-lambda-destroy"></a>

恭喜您！您已使用 适用于 JavaScript 的 AWS SDK通过 Amazon API Gateway 调用了 Lambda 函数。如本教程开头所述，请务必在学习本教程时终止您创建的所有资源，以确保系统不会向您收费。为此，您可以删除在本教程[创建 AWS 资源](#api-gateway-invoking-lambda-provision-resources)主题中创建的 CloudFormation 堆栈，如下所示：

1. [CloudFormation 在 AWS 管理控制台中]( https://console.aws.amazon.com/cloudformation/home)打开。

1. 打开**堆栈**页面，然后选择堆栈。

1. 选择**删除**。