定义采用 TypeScript 的 Lambda 函数处理程序 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

定义采用 TypeScript 的 Lambda 函数处理程序

Lambda 函数处理程序是函数代码中处理事件的方法。当调用函数时,Lambda 运行处理程序方法。您的函数会一直运行,直到处理程序返回响应、退出或超时。

例 TypeScript 处理程序

此示例函数记录事件对象的内容并返回日志的位置。请注意以下几点:

  • 在 Lambda 函数中使用此代码之前,必须添加 @types/aws-lambda 程序包作为开发依赖项。此程序包包含 Lambda 的类型定义。安装 @types/aws-lambda 时,import 语句 (import ... from 'aws-lambda') 会导入类型定义。它不导入 aws-lambda NPM 程序包,这是一个无关的第三方工具。有关更多信息,请参阅 DefinitelyTyped GitHub 存储库中的 aws-lambda

  • 本示例中的处理程序是 ES 模块,必须位于 package.json 文件中或使用 .mjs 文件扩展名进行指定。有关详细信息,请参阅 将函数处理程序指定为 ES 模块

import { Handler } from 'aws-lambda'; export const handler: Handler = async (event, context) => { console.log('EVENT: \n' + JSON.stringify(event, null, 2)); return context.logStreamName; };

运行时会将参数传递到处理程序方法。第一个参数是 event 对象,它包含来自调用方的信息。调用程序在调用 Invoke 时将该信息作为 JSON 格式字符串传递,运行时将它转换为对象。当 Amazon 服务调用您的函数时,事件结构因服务而异。对于 TypeScript,建议对事件对象使用类型注释。有关更多信息,请参阅 将类型用于事件对象

第二个参数是 context 对象,它包含有关调用、函数和执行环境的信息。在前面的示例中,函数将从 context 对象获取日志流的名称,然后将其返回给调用方。

您也可以使用回调参数,这是一种可在非异步处理程序中进行调用以发送响应的函数。我们建议您使用 Async/await(异步/等待),而不使用 Callback(回调)。Async/await 具有更好的易读性、错误处理能力和效率。有关 Async/await 与 Callback 之间差异的更多信息,请参阅 使用回调

使用异步/等待

如果您的代码执行异步任务,则使用 Async/await 模式来确保处理程序会完成运行。Async/await 是一种简洁、易读的 Node.js 异步代码编写方式,无需嵌套回调或链式承诺。使用 Async/await 时,您编写的代码看起来与同步代码类似,同时仍然是异步和非阻止式的。

async 关键字会将函数标记为异步,await 关键字会暂停函数的执行,直到 Promise 完成解析为止。

例 TypeScript 函数 - 异步

此示例使用 fetch,它支持 nodejs18.x 运行时。请注意以下几点:

  • 在 Lambda 函数中使用此代码之前,必须添加 @types/aws-lambda 程序包作为开发依赖项。此程序包包含 Lambda 的类型定义。安装 @types/aws-lambda 时,import 语句 (import ... from 'aws-lambda') 会导入类型定义。它不导入 aws-lambda NPM 程序包,这是一个无关的第三方工具。有关更多信息,请参阅 DefinitelyTyped GitHub 存储库中的 aws-lambda

  • 本示例中的处理程序是 ES 模块,必须位于 package.json 文件中或使用 .mjs 文件扩展名进行指定。有关详细信息,请参阅 将函数处理程序指定为 ES 模块

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda'; const url = 'https://aws.amazon.com/'; export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { try { // fetch is available with Node.js 18 const res = await fetch(url); return { statusCode: res.status, body: JSON.stringify({ message: await res.text(), }), }; } catch (err) { console.log(err); return { statusCode: 500, body: JSON.stringify({ message: 'some error happened', }), }; } };

使用回调

我们建议您使用 Async/await 来声明函数处理程序,而不是使用回调。Async/await 是更好的选择,原因有以下几点:

  • 易读性:Async/await 代码比回调代码更易阅读和理解,回调代码很快就会变得难以理解,从而导致回调失败。

  • 调试和错误处理:基于回调的代码可能非常难以调试。调用堆栈可能变得难以理解,并且很容易出现错误。使用 Async/await 时,您可以使用 try/catch 块来处理错误。

  • 效率:回调通常需要在代码的不同部分之间切换。Async/await 可以减少上下文切换的数量,从而提高代码效率。

当您在处理程序中使用回调时,函数会一直执行,直到 事件循环 为空或函数超时为止。在完成所有事件循环任务之前,不会将响应发送给调用方。如果函数超时,则会返回 error。可以通过将 context.callbackWaitsForEmptyEventLoop 设置为 false,从而将运行时配置为立即发送响应。

callback 函数有两个参数:一个是 Error,一个是响应。响应对象必须与 JSON.stringify 兼容。

例 包含回调的 TypeScript 函数

此示例函数接收来自 Amazon API Gateway 的事件、记录事件和上下文对象,然后向 API Gateway 返回响应。请注意以下几点:

  • 在 Lambda 函数中使用此代码之前,必须添加 @types/aws-lambda 程序包作为开发依赖项。此程序包包含 Lambda 的类型定义。安装 @types/aws-lambda 时,import 语句 (import ... from 'aws-lambda') 会导入类型定义。它不导入 aws-lambda NPM 程序包,这是一个无关的第三方工具。有关更多信息,请参阅 DefinitelyTyped GitHub 存储库中的 aws-lambda

  • 本示例中的处理程序是 ES 模块,必须位于 package.json 文件中或使用 .mjs 文件扩展名进行指定。有关详细信息,请参阅 将函数处理程序指定为 ES 模块

import { Context, APIGatewayProxyCallback, APIGatewayEvent } from 'aws-lambda'; export const lambdaHandler = (event: APIGatewayEvent, context: Context, callback: APIGatewayProxyCallback): void => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); callback(null, { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }); };

将类型用于事件对象

我们建议您不要将任何类型用于处理程序参数和返回类型,因为您将失去检查类型的能力。相反,请使用 sam local generate-event Amazon Serverless Application Model CLI 命令或者使用来自 @types/aws-lambda 软件包的开源定义生成事件。

使用 sam local generate-event 命令生成事件
  1. 生成 Amazon Simple Storage Service (Amazon S3) 代理事件。

    sam local generate-event s3 put >> S3PutEvent.json
  2. 使用 quicktype 实用工具S3PutEvent.json 文件生成类型定义。

    npm install -g quicktype quicktype S3PutEvent.json -o S3PutEvent.ts
  3. 在您的代码中使用生成的类型。

    import { S3PutEvent } from './S3PutEvent'; export const lambdaHandler = async (event: S3PutEvent): Promise<void> => { event.Records.map((record) => console.log(record.s3.object.key)); };
使用来自 @types/aws-lambda 软件包的开源定义生成事件
  1. 添加 @types/aws-lambda 软件包作为开发依赖项。

    npm install -D @types/aws-lambda
  2. 在您的代码中使用这些类型。

    import { S3Event } from "aws-lambda"; export const lambdaHandler = async (event: S3Event): Promise<void> => { event.Records.map((record) => console.log(record.s3.object.key)); };