使用 f SDK or JavaScript (v3) 的 Lambda 示例 - AWS SDK代码示例

AWS 文档 AWS SDK示例 GitHub 存储库中还有更多SDK示例

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

使用 f SDK or JavaScript (v3) 的 Lambda 示例

以下代码示例向您展示了如何使用带有 Lambda 的 AWS SDK for JavaScript (v3) 来执行操作和实现常见场景。

基础知识是向您展示如何在服务中执行基本操作的代码示例。

操作是大型程序的代码摘录,必须在上下文中运行。您可以通过操作了解如何调用单个服务函数,还可以通过函数相关场景的上下文查看操作。

场景是向您展示如何通过在一个服务中调用多个函数或与其他 AWS 服务结合来完成特定任务的代码示例。

每个示例都包含一个指向完整源代码的链接,您可以在其中找到有关如何在上下文中设置和运行代码的说明。

开始使用

以下代码示例展示了如何开始使用 Lambda。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

import { LambdaClient, paginateListFunctions } from "@aws-sdk/client-lambda"; const client = new LambdaClient({}); export const helloLambda = async () => { const paginator = paginateListFunctions({ client }, {}); const functions = []; for await (const page of paginator) { const funcNames = page.Functions.map((f) => f.FunctionName); functions.push(...funcNames); } console.log("Functions:"); console.log(functions.join("\n")); return functions; };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 ListFunctions” 中的。

基础知识

以下代码示例展示了如何:

  • 创建IAM角色和 Lambda 函数,然后上传处理程序代码。

  • 使用单个参数来调用函数并获取结果。

  • 更新函数代码并使用环境变量进行配置。

  • 使用新参数来调用函数并获取结果。显示返回的执行日志。

  • 列出账户函数,然后清除函数。

有关更多信息,请参阅使用控制台创建 Lambda 函数

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

创建一个 AWS Identity and Access Management (IAM) 角色来授予 Lambda 写入日志的权限。

logger.log(`Creating role (${NAME_ROLE_LAMBDA})...`); const response = await createRole(NAME_ROLE_LAMBDA); import { AttachRolePolicyCommand, IAMClient } from "@aws-sdk/client-iam"; const client = new IAMClient({}); /** * * @param {string} policyArn * @param {string} roleName */ export const attachRolePolicy = (policyArn, roleName) => { const command = new AttachRolePolicyCommand({ PolicyArn: policyArn, RoleName: roleName, }); return client.send(command); };

创建 Lambda 函数并上传处理程序代码。

const createFunction = async (funcName, roleArn) => { const client = new LambdaClient({}); const code = await readFile(`${dirname}../functions/${funcName}.zip`); const command = new CreateFunctionCommand({ Code: { ZipFile: code }, FunctionName: funcName, Role: roleArn, Architectures: [Architecture.arm64], Handler: "index.handler", // Required when sending a .zip file PackageType: PackageType.Zip, // Required when sending a .zip file Runtime: Runtime.nodejs16x, // Required when sending a .zip file }); return client.send(command); };

调用单参数函数并得出结果。

const invoke = async (funcName, payload) => { const client = new LambdaClient({}); const command = new InvokeCommand({ FunctionName: funcName, Payload: JSON.stringify(payload), LogType: LogType.Tail, }); const { Payload, LogResult } = await client.send(command); const result = Buffer.from(Payload).toString(); const logs = Buffer.from(LogResult, "base64").toString(); return { logs, result }; };

更新函数代码并使用环境变量配置其 Lambda 环境。

const updateFunctionCode = async (funcName, newFunc) => { const client = new LambdaClient({}); const code = await readFile(`${dirname}../functions/${newFunc}.zip`); const command = new UpdateFunctionCodeCommand({ ZipFile: code, FunctionName: funcName, Architectures: [Architecture.arm64], Handler: "index.handler", // Required when sending a .zip file PackageType: PackageType.Zip, // Required when sending a .zip file Runtime: Runtime.nodejs16x, // Required when sending a .zip file }); return client.send(command); }; const updateFunctionConfiguration = (funcName) => { const client = new LambdaClient({}); const config = readFileSync(`${dirname}../functions/config.json`).toString(); const command = new UpdateFunctionConfigurationCommand({ ...JSON.parse(config), FunctionName: funcName, }); const result = client.send(command); waitForFunctionUpdated({ FunctionName: funcName }); return result; };

列出您账户的函数。

const listFunctions = () => { const client = new LambdaClient({}); const command = new ListFunctionsCommand({}); return client.send(command); };

删除该IAM角色和 Lambda 函数。

import { DeleteRoleCommand, IAMClient } from "@aws-sdk/client-iam"; const client = new IAMClient({}); /** * * @param {string} roleName */ export const deleteRole = (roleName) => { const command = new DeleteRoleCommand({ RoleName: roleName }); return client.send(command); }; /** * @param {string} funcName */ const deleteFunction = (funcName) => { const client = new LambdaClient({}); const command = new DeleteFunctionCommand({ FunctionName: funcName }); return client.send(command); };

操作

以下代码示例演示如何使用 CreateFunction

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const createFunction = async (funcName, roleArn) => { const client = new LambdaClient({}); const code = await readFile(`${dirname}../functions/${funcName}.zip`); const command = new CreateFunctionCommand({ Code: { ZipFile: code }, FunctionName: funcName, Role: roleArn, Architectures: [Architecture.arm64], Handler: "index.handler", // Required when sending a .zip file PackageType: PackageType.Zip, // Required when sending a .zip file Runtime: Runtime.nodejs16x, // Required when sending a .zip file }); return client.send(command); };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 CreateFunction” 中的。

以下代码示例演示如何使用 DeleteFunction

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

/** * @param {string} funcName */ const deleteFunction = (funcName) => { const client = new LambdaClient({}); const command = new DeleteFunctionCommand({ FunctionName: funcName }); return client.send(command); };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 DeleteFunction” 中的。

以下代码示例演示如何使用 GetFunction

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const getFunction = (funcName) => { const client = new LambdaClient({}); const command = new GetFunctionCommand({ FunctionName: funcName }); return client.send(command); };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 GetFunction” 中的。

以下代码示例演示如何使用 Invoke

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const invoke = async (funcName, payload) => { const client = new LambdaClient({}); const command = new InvokeCommand({ FunctionName: funcName, Payload: JSON.stringify(payload), LogType: LogType.Tail, }); const { Payload, LogResult } = await client.send(command); const result = Buffer.from(Payload).toString(); const logs = Buffer.from(LogResult, "base64").toString(); return { logs, result }; };
  • 有关API详细信息,请参见在AWS SDK for JavaScript API参考中

以下代码示例演示如何使用 ListFunctions

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const listFunctions = () => { const client = new LambdaClient({}); const command = new ListFunctionsCommand({}); return client.send(command); };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 ListFunctions” 中的。

以下代码示例演示如何使用 UpdateFunctionCode

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const updateFunctionCode = async (funcName, newFunc) => { const client = new LambdaClient({}); const code = await readFile(`${dirname}../functions/${newFunc}.zip`); const command = new UpdateFunctionCodeCommand({ ZipFile: code, FunctionName: funcName, Architectures: [Architecture.arm64], Handler: "index.handler", // Required when sending a .zip file PackageType: PackageType.Zip, // Required when sending a .zip file Runtime: Runtime.nodejs16x, // Required when sending a .zip file }); return client.send(command); };
  • 有关API详细信息,请参阅 “AWS SDK for JavaScript API参考 UpdateFunctionCode” 中的。

以下代码示例演示如何使用 UpdateFunctionConfiguration

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

const updateFunctionConfiguration = (funcName) => { const client = new LambdaClient({}); const config = readFileSync(`${dirname}../functions/config.json`).toString(); const command = new UpdateFunctionConfigurationCommand({ ...JSON.parse(config), FunctionName: funcName, }); const result = client.send(command); waitForFunctionUpdated({ FunctionName: funcName }); return result; };

场景

以下代码示例显示了如何使用 Lambda 函数自动确认已知的 Amazon Cognito 用户。

  • 配置用户池以调用 PreSignUp 触发器的 Lambda 函数。

  • 将用户注册到 Amazon Cognito

  • Lambda 函数会扫描 DynamoDB 表并自动确认已知用户。

  • 以新用户身份登录,然后清理资源。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。查找完整示例,学习如何在 AWS 代码示例存储库中进行设置和运行。

配置交互式 “场景” 运行。 JavaScript (v3) 示例共享一个场景运行器,以简化复杂的示例。完整的源代码已打开 GitHub。

import { AutoConfirm } from "./scenario-auto-confirm.js"; /** * The context is passed to every scenario. Scenario steps * will modify the context. */ const context = { errors: [], users: [ { UserName: "test_user_1", UserEmail: "test_email_1@example.com", }, { UserName: "test_user_2", UserEmail: "test_email_2@example.com", }, { UserName: "test_user_3", UserEmail: "test_email_3@example.com", }, ], }; /** * Three Scenarios are created for the workflow. A Scenario is an orchestration class * that simplifies running a series of steps. */ export const scenarios = { // Demonstrate automatically confirming known users in a database. "auto-confirm": AutoConfirm(context), }; // Call function if run directly import { fileURLToPath } from "node:url"; import { parseScenarioArgs } from "@aws-doc-sdk-examples/lib/scenario/index.js"; if (process.argv[1] === fileURLToPath(import.meta.url)) { parseScenarioArgs(scenarios, { name: "Cognito user pools and triggers", description: "Demonstrate how to use the AWS SDKs to customize Amazon Cognito authentication behavior.", }); }

此场景演示自动确认已知用户。它编排了示例步骤。

import { wait } from "@aws-doc-sdk-examples/lib/utils/util-timers.js"; import { Scenario, ScenarioAction, ScenarioInput, ScenarioOutput, } from "@aws-doc-sdk-examples/lib/scenario/scenario.js"; import { getStackOutputs, logCleanUpReminder, promptForStackName, promptForStackRegion, skipWhenErrors, } from "./steps-common.js"; import { populateTable } from "./actions/dynamodb-actions.js"; import { addPreSignUpHandler, deleteUser, getUser, signIn, signUpUser, } from "./actions/cognito-actions.js"; import { getLatestLogStreamForLambda, getLogEvents, } from "./actions/cloudwatch-logs-actions.js"; /** * @typedef {{ * errors: Error[], * password: string, * users: { UserName: string, UserEmail: string }[], * selectedUser?: string, * stackName?: string, * stackRegion?: string, * token?: string, * confirmDeleteSignedInUser?: boolean, * TableName?: string, * UserPoolClientId?: string, * UserPoolId?: string, * UserPoolArn?: string, * AutoConfirmHandlerArn?: string, * AutoConfirmHandlerName?: string * }} State */ const greeting = new ScenarioOutput( "greeting", (/** @type {State} */ state) => `This demo will populate some users into the \ database created as part of the "${state.stackName}" stack. \ Then the autoConfirmHandler will be linked to the PreSignUp \ trigger from Cognito. Finally, you will choose a user to sign up.`, { skipWhen: skipWhenErrors }, ); const logPopulatingUsers = new ScenarioOutput( "logPopulatingUsers", "Populating the DynamoDB table with some users.", { skipWhenErrors: skipWhenErrors }, ); const logPopulatingUsersComplete = new ScenarioOutput( "logPopulatingUsersComplete", "Done populating users.", { skipWhen: skipWhenErrors }, ); const populateUsers = new ScenarioAction( "populateUsers", async (/** @type {State} */ state) => { const [_, err] = await populateTable({ region: state.stackRegion, tableName: state.TableName, items: state.users, }); if (err) { state.errors.push(err); } }, { skipWhen: skipWhenErrors, }, ); const logSetupSignUpTrigger = new ScenarioOutput( "logSetupSignUpTrigger", "Setting up the PreSignUp trigger for the Cognito User Pool.", { skipWhen: skipWhenErrors }, ); const setupSignUpTrigger = new ScenarioAction( "setupSignUpTrigger", async (/** @type {State} */ state) => { const [_, err] = await addPreSignUpHandler({ region: state.stackRegion, userPoolId: state.UserPoolId, handlerArn: state.AutoConfirmHandlerArn, }); if (err) { state.errors.push(err); } }, { skipWhen: skipWhenErrors, }, ); const logSetupSignUpTriggerComplete = new ScenarioOutput( "logSetupSignUpTriggerComplete", ( /** @type {State} */ state, ) => `The lambda function "${state.AutoConfirmHandlerName}" \ has been configured as the PreSignUp trigger handler for the user pool "${state.UserPoolId}".`, { skipWhen: skipWhenErrors }, ); const selectUser = new ScenarioInput( "selectedUser", "Select a user to sign up.", { type: "select", choices: (/** @type {State} */ state) => state.users.map((u) => u.UserName), skipWhen: skipWhenErrors, default: (/** @type {State} */ state) => state.users[0].UserName, }, ); const checkIfUserAlreadyExists = new ScenarioAction( "checkIfUserAlreadyExists", async (/** @type {State} */ state) => { const [user, err] = await getUser({ region: state.stackRegion, userPoolId: state.UserPoolId, username: state.selectedUser, }); if (err?.name === "UserNotFoundException") { // Do nothing. We're not expecting the user to exist before // sign up is complete. return; } if (err) { state.errors.push(err); return; } if (user) { state.errors.push( new Error( `The user "${state.selectedUser}" already exists in the user pool "${state.UserPoolId}".`, ), ); } }, { skipWhen: skipWhenErrors, }, ); const createPassword = new ScenarioInput( "password", "Enter a password that has at least eight characters, uppercase, lowercase, numbers and symbols.", { type: "password", skipWhen: skipWhenErrors, default: "Abcd1234!" }, ); const logSignUpExistingUser = new ScenarioOutput( "logSignUpExistingUser", (/** @type {State} */ state) => `Signing up user "${state.selectedUser}".`, { skipWhen: skipWhenErrors }, ); const signUpExistingUser = new ScenarioAction( "signUpExistingUser", async (/** @type {State} */ state) => { const signUp = (password) => signUpUser({ region: state.stackRegion, userPoolClientId: state.UserPoolClientId, username: state.selectedUser, email: state.users.find((u) => u.UserName === state.selectedUser) .UserEmail, password, }); let [_, err] = await signUp(state.password); while (err?.name === "InvalidPasswordException") { console.warn("The password you entered was invalid."); await createPassword.handle(state); [_, err] = await signUp(state.password); } if (err) { state.errors.push(err); } }, { skipWhen: skipWhenErrors }, ); const logSignUpExistingUserComplete = new ScenarioOutput( "logSignUpExistingUserComplete", (/** @type {State} */ state) => `"${state.selectedUser} was signed up successfully.`, { skipWhen: skipWhenErrors }, ); const logLambdaLogs = new ScenarioAction( "logLambdaLogs", async (/** @type {State} */ state) => { console.log( "Waiting a few seconds to let Lambda write to CloudWatch Logs...\n", ); await wait(10); const [logStream, logStreamErr] = await getLatestLogStreamForLambda({ functionName: state.AutoConfirmHandlerName, region: state.stackRegion, }); if (logStreamErr) { state.errors.push(logStreamErr); return; } console.log( `Getting some recent events from log stream "${logStream.logStreamName}"`, ); const [logEvents, logEventsErr] = await getLogEvents({ functionName: state.AutoConfirmHandlerName, region: state.stackRegion, eventCount: 10, logStreamName: logStream.logStreamName, }); if (logEventsErr) { state.errors.push(logEventsErr); return; } console.log(logEvents.map((ev) => `\t${ev.message}`).join("")); }, { skipWhen: skipWhenErrors }, ); const logSignInUser = new ScenarioOutput( "logSignInUser", (/** @type {State} */ state) => `Let's sign in as ${state.selectedUser}`, { skipWhen: skipWhenErrors }, ); const signInUser = new ScenarioAction( "signInUser", async (/** @type {State} */ state) => { const [response, err] = await signIn({ region: state.stackRegion, clientId: state.UserPoolClientId, username: state.selectedUser, password: state.password, }); if (err?.name === "PasswordResetRequiredException") { state.errors.push(new Error("Please reset your password.")); return; } if (err) { state.errors.push(err); return; } state.token = response?.AuthenticationResult?.AccessToken; }, { skipWhen: skipWhenErrors }, ); const logSignInUserComplete = new ScenarioOutput( "logSignInUserComplete", (/** @type {State} */ state) => `Successfully signed in. Your access token starts with: ${state.token.slice(0, 11)}`, { skipWhen: skipWhenErrors }, ); const confirmDeleteSignedInUser = new ScenarioInput( "confirmDeleteSignedInUser", "Do you want to delete the currently signed in user?", { type: "confirm", skipWhen: skipWhenErrors }, ); const deleteSignedInUser = new ScenarioAction( "deleteSignedInUser", async (/** @type {State} */ state) => { const [_, err] = await deleteUser({ region: state.stackRegion, accessToken: state.token, }); if (err) { state.errors.push(err); } }, { skipWhen: (/** @type {State} */ state) => skipWhenErrors(state) || !state.confirmDeleteSignedInUser, }, ); const logErrors = new ScenarioOutput( "logErrors", (/** @type {State}*/ state) => { const errorList = state.errors .map((err) => ` - ${err.name}: ${err.message}`) .join("\n"); return `Scenario errors found:\n${errorList}`; }, { // Don't log errors when there aren't any! skipWhen: (/** @type {State} */ state) => state.errors.length === 0, }, ); export const AutoConfirm = (context) => new Scenario( "AutoConfirm", [ promptForStackName, promptForStackRegion, getStackOutputs, greeting, logPopulatingUsers, populateUsers, logPopulatingUsersComplete, logSetupSignUpTrigger, setupSignUpTrigger, logSetupSignUpTriggerComplete, selectUser, checkIfUserAlreadyExists, createPassword, logSignUpExistingUser, signUpExistingUser, logSignUpExistingUserComplete, logLambdaLogs, logSignInUser, signInUser, logSignInUserComplete, confirmDeleteSignedInUser, deleteSignedInUser, logCleanUpReminder, logErrors, ], context, );

这些步骤与其他场景共享。

import { ScenarioAction, ScenarioInput, ScenarioOutput, } from "@aws-doc-sdk-examples/lib/scenario/scenario.js"; import { getCfnOutputs } from "@aws-doc-sdk-examples/lib/sdk/cfn-outputs.js"; export const skipWhenErrors = (state) => state.errors.length > 0; export const getStackOutputs = new ScenarioAction( "getStackOutputs", async (state) => { if (!state.stackName || !state.stackRegion) { state.errors.push( new Error( "No stack name or region provided. The stack name and \ region are required to fetch CFN outputs relevant to this example.", ), ); return; } const outputs = await getCfnOutputs(state.stackName, state.stackRegion); Object.assign(state, outputs); }, ); export const promptForStackName = new ScenarioInput( "stackName", "Enter the name of the stack you deployed earlier.", { type: "input", default: "PoolsAndTriggersStack" }, ); export const promptForStackRegion = new ScenarioInput( "stackRegion", "Enter the region of the stack you deployed earlier.", { type: "input", default: "us-east-1" }, ); export const logCleanUpReminder = new ScenarioOutput( "logCleanUpReminder", "All done. Remember to run 'cdk destroy' to teardown the stack.", { skipWhen: skipWhenErrors }, );

带有 Lambda 函数的PreSignUp触发器的处理程序。

import type { PreSignUpTriggerEvent, Handler } from "aws-lambda"; import type { UserRepository } from "./user-repository"; import { DynamoDBUserRepository } from "./user-repository"; export class PreSignUpHandler { private userRepository: UserRepository; constructor(userRepository: UserRepository) { this.userRepository = userRepository; } private isPreSignUpTriggerSource(event: PreSignUpTriggerEvent): boolean { return event.triggerSource === "PreSignUp_SignUp"; } private getEventUserEmail(event: PreSignUpTriggerEvent): string { return event.request.userAttributes.email; } async handlePreSignUpTriggerEvent( event: PreSignUpTriggerEvent, ): Promise<PreSignUpTriggerEvent> { console.log( `Received presignup from ${event.triggerSource} for user '${event.userName}'`, ); if (!this.isPreSignUpTriggerSource(event)) { return event; } const eventEmail = this.getEventUserEmail(event); console.log(`Looking up email ${eventEmail}.`); const storedUserInfo = await this.userRepository.getUserInfoByEmail(eventEmail); if (!storedUserInfo) { console.log( `Email ${eventEmail} not found. Email verification is required.`, ); return event; } if (storedUserInfo.UserName !== event.userName) { console.log( `UserEmail ${eventEmail} found, but stored UserName '${storedUserInfo.UserName}' does not match supplied UserName '${event.userName}'. Verification is required.`, ); } else { console.log( `UserEmail ${eventEmail} found with matching UserName ${storedUserInfo.UserName}. User is confirmed.`, ); event.response.autoConfirmUser = true; event.response.autoVerifyEmail = true; } return event; } } const createPreSignUpHandler = (): PreSignUpHandler => { const tableName = process.env.TABLE_NAME; if (!tableName) { throw new Error("TABLE_NAME environment variable is not set"); } const userRepository = new DynamoDBUserRepository(tableName); return new PreSignUpHandler(userRepository); }; export const handler: Handler = async (event: PreSignUpTriggerEvent) => { const preSignUpHandler = createPreSignUpHandler(); return preSignUpHandler.handlePreSignUpTriggerEvent(event); };

CloudWatch 日志操作模块。

import { CloudWatchLogsClient, GetLogEventsCommand, OrderBy, paginateDescribeLogStreams, } from "@aws-sdk/client-cloudwatch-logs"; /** * Get the latest log stream for a Lambda function. * @param {{ functionName: string, region: string }} config * @returns {Promise<[import("@aws-sdk/client-cloudwatch-logs").LogStream | null, unknown]>} */ export const getLatestLogStreamForLambda = async ({ functionName, region }) => { try { const logGroupName = `/aws/lambda/${functionName}`; const cwlClient = new CloudWatchLogsClient({ region }); const paginator = paginateDescribeLogStreams( { client: cwlClient }, { descending: true, limit: 1, orderBy: OrderBy.LastEventTime, logGroupName, }, ); for await (const page of paginator) { return [page.logStreams[0], null]; } } catch (err) { return [null, err]; } }; /** * Get the log events for a Lambda function's log stream. * @param {{ * functionName: string, * logStreamName: string, * eventCount: number, * region: string * }} config * @returns {Promise<[import("@aws-sdk/client-cloudwatch-logs").OutputLogEvent[] | null, unknown]>} */ export const getLogEvents = async ({ functionName, logStreamName, eventCount, region, }) => { try { const cwlClient = new CloudWatchLogsClient({ region }); const logGroupName = `/aws/lambda/${functionName}`; const response = await cwlClient.send( new GetLogEventsCommand({ logStreamName: logStreamName, limit: eventCount, logGroupName: logGroupName, }), ); return [response.events, null]; } catch (err) { return [null, err]; } };

亚马逊 Cognito 操作模块。

import { AdminGetUserCommand, CognitoIdentityProviderClient, DeleteUserCommand, InitiateAuthCommand, SignUpCommand, UpdateUserPoolCommand, } from "@aws-sdk/client-cognito-identity-provider"; /** * Connect a Lambda function to the PreSignUp trigger for a Cognito user pool * @param {{ region: string, userPoolId: string, handlerArn: string }} config * @returns {Promise<[import("@aws-sdk/client-cognito-identity-provider").UpdateUserPoolCommandOutput | null, unknown]>} */ export const addPreSignUpHandler = async ({ region, userPoolId, handlerArn, }) => { try { const cognitoClient = new CognitoIdentityProviderClient({ region, }); const command = new UpdateUserPoolCommand({ UserPoolId: userPoolId, LambdaConfig: { PreSignUp: handlerArn, }, }); const response = await cognitoClient.send(command); return [response, null]; } catch (err) { return [null, err]; } }; /** * Attempt to register a user to a user pool with a given username and password. * @param {{ * region: string, * userPoolClientId: string, * username: string, * email: string, * password: string * }} config * @returns {Promise<[import("@aws-sdk/client-cognito-identity-provider").SignUpCommandOutput | null, unknown]>} */ export const signUpUser = async ({ region, userPoolClientId, username, email, password, }) => { try { const cognitoClient = new CognitoIdentityProviderClient({ region, }); const response = await cognitoClient.send( new SignUpCommand({ ClientId: userPoolClientId, Username: username, Password: password, UserAttributes: [{ Name: "email", Value: email }], }), ); return [response, null]; } catch (err) { return [null, err]; } }; /** * Sign in a user to Amazon Cognito using a username and password authentication flow. * @param {{ region: string, clientId: string, username: string, password: string }} config * @returns {Promise<[import("@aws-sdk/client-cognito-identity-provider").InitiateAuthCommandOutput | null, unknown]>} */ export const signIn = async ({ region, clientId, username, password }) => { try { const cognitoClient = new CognitoIdentityProviderClient({ region }); const response = await cognitoClient.send( new InitiateAuthCommand({ AuthFlow: "USER_PASSWORD_AUTH", ClientId: clientId, AuthParameters: { USERNAME: username, PASSWORD: password }, }), ); return [response, null]; } catch (err) { return [null, err]; } }; /** * Retrieve an existing user from a user pool. * @param {{ region: string, userPoolId: string, username: string }} config * @returns {Promise<[import("@aws-sdk/client-cognito-identity-provider").AdminGetUserCommandOutput | null, unknown]>} */ export const getUser = async ({ region, userPoolId, username }) => { try { const cognitoClient = new CognitoIdentityProviderClient({ region }); const response = await cognitoClient.send( new AdminGetUserCommand({ UserPoolId: userPoolId, Username: username, }), ); return [response, null]; } catch (err) { return [null, err]; } }; /** * Delete the signed-in user. Useful for allowing a user to delete their * own profile. * @param {{ region: string, accessToken: string }} config * @returns {Promise<[import("@aws-sdk/client-cognito-identity-provider").DeleteUserCommandOutput | null, unknown]>} */ export const deleteUser = async ({ region, accessToken }) => { try { const client = new CognitoIdentityProviderClient({ region }); const response = await client.send( new DeleteUserCommand({ AccessToken: accessToken }), ); return [response, null]; } catch (err) { return [null, err]; } };

DynamoDB 操作模块。

import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { BatchWriteCommand, DynamoDBDocumentClient, } from "@aws-sdk/lib-dynamodb"; /** * Populate a DynamoDB table with provide items. * @param {{ region: string, tableName: string, items: Record<string, unknown>[] }} config * @returns {Promise<[import("@aws-sdk/lib-dynamodb").BatchWriteCommandOutput | null, unknown]>} */ export const populateTable = async ({ region, tableName, items }) => { try { const ddbClient = new DynamoDBClient({ region }); const docClient = DynamoDBDocumentClient.from(ddbClient); const response = await docClient.send( new BatchWriteCommand({ RequestItems: { [tableName]: items.map((item) => ({ PutRequest: { Item: item, }, })), }, }), ); return [response, null]; } catch (err) { return [null, err]; } };

以下代码示例演示如何创建无服务器应用程序,让用户能够使用标签管理照片。

SDK对于 JavaScript (v3)

演示如何开发照片资产管理应用程序,该应用程序使用 Amazon Rekognition 检测图像中的标签并将其存储以供日后检索。

有关如何设置和运行的完整源代码和说明,请参阅上的完整示例 GitHub

要深入了解这个例子的起源,请参阅 AWS 社区上的博文。

本示例中使用的服务
  • API网关

  • DynamoDB

  • Lambda

  • Amazon Rekognition

  • Amazon S3

  • Amazon SNS

以下代码示例说明如何创建应用程序来分析客户意见卡、翻译其母语、确定其情绪并根据译后的文本生成音频文件。

SDK对于 JavaScript (v3)

此示例应用程序可分析并存储客户反馈卡。具体来说,它满足了纽约市一家虚构酒店的需求。酒店以实体意见卡的形式收集来自不同语种的客人的反馈。该反馈通过 Web 客户端上传到应用程序中。意见卡图片上传后,将执行以下步骤:

  • 使用 Amazon Textract 从图片中提取文本。

  • Amazon Comprehend 确定所提取文本的情绪及其语言。

  • 使用 Amazon Translate 将所提取文本翻译为英语。

  • Amazon Polly 根据所提取文本合成音频文件。

完整的应用程序可使用  AWS CDK 进行部署。有关源代码和部署说明,请参阅中的项目 GitHub。以下摘录显示了在 Lambda 函数中 AWS SDK for JavaScript 是如何使用的。

import { ComprehendClient, DetectDominantLanguageCommand, DetectSentimentCommand, } from "@aws-sdk/client-comprehend"; /** * Determine the language and sentiment of the extracted text. * * @param {{ source_text: string}} extractTextOutput */ export const handler = async (extractTextOutput) => { const comprehendClient = new ComprehendClient({}); const detectDominantLanguageCommand = new DetectDominantLanguageCommand({ Text: extractTextOutput.source_text, }); // The source language is required for sentiment analysis and // translation in the next step. const { Languages } = await comprehendClient.send( detectDominantLanguageCommand, ); const languageCode = Languages[0].LanguageCode; const detectSentimentCommand = new DetectSentimentCommand({ Text: extractTextOutput.source_text, LanguageCode: languageCode, }); const { Sentiment } = await comprehendClient.send(detectSentimentCommand); return { sentiment: Sentiment, language_code: languageCode, }; };
import { DetectDocumentTextCommand, TextractClient, } from "@aws-sdk/client-textract"; /** * Fetch the S3 object from the event and analyze it using Amazon Textract. * * @param {import("@types/aws-lambda").EventBridgeEvent<"Object Created">} eventBridgeS3Event */ export const handler = async (eventBridgeS3Event) => { const textractClient = new TextractClient(); const detectDocumentTextCommand = new DetectDocumentTextCommand({ Document: { S3Object: { Bucket: eventBridgeS3Event.bucket, Name: eventBridgeS3Event.object, }, }, }); // Textract returns a list of blocks. A block can be a line, a page, word, etc. // Each block also contains geometry of the detected text. // For more information on the Block type, see https://docs.aws.amazon.com/textract/latest/dg/API_Block.html. const { Blocks } = await textractClient.send(detectDocumentTextCommand); // For the purpose of this example, we are only interested in words. const extractedWords = Blocks.filter((b) => b.BlockType === "WORD").map( (b) => b.Text, ); return extractedWords.join(" "); };
import { PollyClient, SynthesizeSpeechCommand } from "@aws-sdk/client-polly"; import { S3Client } from "@aws-sdk/client-s3"; import { Upload } from "@aws-sdk/lib-storage"; /** * Synthesize an audio file from text. * * @param {{ bucket: string, translated_text: string, object: string}} sourceDestinationConfig */ export const handler = async (sourceDestinationConfig) => { const pollyClient = new PollyClient({}); const synthesizeSpeechCommand = new SynthesizeSpeechCommand({ Engine: "neural", Text: sourceDestinationConfig.translated_text, VoiceId: "Ruth", OutputFormat: "mp3", }); const { AudioStream } = await pollyClient.send(synthesizeSpeechCommand); const audioKey = `${sourceDestinationConfig.object}.mp3`; // Store the audio file in S3. const s3Client = new S3Client(); const upload = new Upload({ client: s3Client, params: { Bucket: sourceDestinationConfig.bucket, Key: audioKey, Body: AudioStream, ContentType: "audio/mp3", }, }); await upload.done(); return audioKey; };
import { TranslateClient, TranslateTextCommand, } from "@aws-sdk/client-translate"; /** * Translate the extracted text to English. * * @param {{ extracted_text: string, source_language_code: string}} textAndSourceLanguage */ export const handler = async (textAndSourceLanguage) => { const translateClient = new TranslateClient({}); const translateCommand = new TranslateTextCommand({ SourceLanguageCode: textAndSourceLanguage.source_language_code, TargetLanguageCode: "en", Text: textAndSourceLanguage.extracted_text, }); const { TranslatedText } = await translateClient.send(translateCommand); return { translated_text: TranslatedText }; };
本示例中使用的服务
  • Amazon Comprehend

  • Lambda

  • Amazon Polly

  • Amazon Textract

  • Amazon Translate

以下代码示例显示了如何从浏览器调用 AWS Lambda 函数。

SDK对于 JavaScript (v3)

您可以创建一个基于浏览器的应用程序,该应用程序使用 AWS Lambda 函数更新包含用户选择的 Amazon DynamoDB 表。此应用程序使用 AWS SDK for JavaScript v3。

有关如何设置和运行的完整源代码和说明,请参阅上的完整示例GitHub

本示例中使用的服务
  • DynamoDB

  • Lambda

以下代码示例展示了如何创建由 Amazon API Gateway 调用的 AWS Lambda 函数。

SDK对于 JavaScript (v3)

演示如何使用 Lambda JavaScript 运行时创建 AWS Lambda 函数。API此示例调用不同的 AWS 服务来执行特定的用例。此示例演示如何创建由 Amazon API Gateway 调用的 Lambda 函数,该函数会扫描亚马逊 DynamoDB 表中的工作周年纪念日,并使用亚马逊简单通知服务 (AmazonSNS) 向您的员工发送一条短信,祝贺他们在一周年之日向他们表示祝贺。

有关如何设置和运行的完整源代码和说明,请参阅上的完整示例GitHub

该示例也可在 AWS SDK for JavaScript v3 开发人员指南中找到。

本示例中使用的服务
  • API网关

  • DynamoDB

  • Lambda

  • Amazon SNS

以下代码示例显示如何创建由 Amazon EventBridge 计划事件调用的 AWS Lambda 函数。

SDK对于 JavaScript (v3)

演示如何创建调用函数的 Amazon EventBridge 计划事件。 AWS Lambda 配置 EventBridge 为使用 cron 表达式来调度 Lambda 函数的调用时间。在此示例中,您将使用 Lambda 运行时创建一个 Lambda 函数。 JavaScript API此示例调用不同的 AWS 服务来执行特定的用例。此示例展示了如何创建一个应用程序,在其一周年纪念日时向员工发送移动短信表示祝贺。

有关如何设置和运行的完整源代码和说明,请参阅上的完整示例GitHub

该示例也可在 AWS SDK for JavaScript v3 开发人员指南中找到。

本示例中使用的服务
  • DynamoDB

  • EventBridge

  • Lambda

  • Amazon SNS

无服务器示例

以下代码示例说明如何实现连接到数据库的 Lambda 函数。RDS该函数发出一个简单的数据库请求并返回结果。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用在 Lambda 函数中连接到亚马逊RDS数据库。 JavaScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 /* Node.js code here. */ // ES6+ example import { Signer } from "@aws-sdk/rds-signer"; import mysql from 'mysql2/promise'; async function createAuthToken() { // Define connection authentication parameters const dbinfo = { hostname: process.env.ProxyHostName, port: process.env.Port, username: process.env.DBUserName, region: process.env.AWS_REGION, } // Create RDS Signer object const signer = new Signer(dbinfo); // Request authorization token from RDS, specifying the username const token = await signer.getAuthToken(); return token; } async function dbOps() { // Obtain auth token const token = await createAuthToken(); // Define connection configuration let connectionConfig = { host: process.env.ProxyHostName, user: process.env.DBUserName, password: token, database: process.env.DBName, ssl: 'Amazon RDS' } // Create the connection to the DB const conn = await mysql.createConnection(connectionConfig); // Obtain the result of the query const [res,] = await conn.execute('select ?+? as sum', [3, 2]); return res; } export const handler = async (event) => { // Execute database flow const result = await dbOps(); // Return result return { statusCode: 200, body: JSON.stringify("The selected sum is: " + result[0].sum) } };

使用在 Lambda 函数中连接到亚马逊RDS数据库。 TypeScript

import { Signer } from "@aws-sdk/rds-signer"; import mysql from 'mysql2/promise'; // RDS settings // Using '!' (non-null assertion operator) to tell the TypeScript compiler that the DB settings are not null or undefined, const proxy_host_name = process.env.PROXY_HOST_NAME! const port = parseInt(process.env.PORT!) const db_name = process.env.DB_NAME! const db_user_name = process.env.DB_USER_NAME! const aws_region = process.env.AWS_REGION! async function createAuthToken(): Promise<string> { // Create RDS Signer object const signer = new Signer({ hostname: proxy_host_name, port: port, region: aws_region, username: db_user_name }); // Request authorization token from RDS, specifying the username const token = await signer.getAuthToken(); return token; } async function dbOps(): Promise<mysql.QueryResult | undefined> { try { // Obtain auth token const token = await createAuthToken(); const conn = await mysql.createConnection({ host: proxy_host_name, user: db_user_name, password: token, database: db_name, ssl: 'Amazon RDS' // Ensure you have the CA bundle for SSL connection }); const [rows, fields] = await conn.execute('SELECT ? + ? AS sum', [3, 2]); console.log('result:', rows); return rows; } catch (err) { console.log(err); } } export const lambdaHandler = async (event: any): Promise<{ statusCode: number; body: string }> => { // Execute database flow const result = await dbOps(); // Return error is result is undefined if (result == undefined) return { statusCode: 500, body: JSON.stringify(`Error with connection to DB host`) } // Return result return { statusCode: 200, body: JSON.stringify(`The selected sum is: ${result[0].sum}`) }; };

以下代码示例展示了如何实现一个 Lambda 函数,该函数接收因接收来自 Kinesis 流的记录而触发的事件。该函数检索 Kinesis 有效负载,将 Base64 解码,并记录下记录内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 消耗 Kinesis 事件。 JavaScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const record of event.Records) { try { console.log(`Processed Kinesis Event - EventID: ${record.eventID}`); const recordData = await getRecordDataAsync(record.kinesis); console.log(`Record Data: ${recordData}`); // TODO: Do interesting work based on the new data } catch (err) { console.error(`An error occurred ${err}`); throw err; } } console.log(`Successfully processed ${event.Records.length} records.`); }; async function getRecordDataAsync(payload) { var data = Buffer.from(payload.data, "base64").toString("utf-8"); await Promise.resolve(1); //Placeholder for actual async work return data; }

使用 Lambda 消耗 Kinesis 事件。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { KinesisStreamEvent, Context, KinesisStreamHandler, KinesisStreamRecordPayload, } from "aws-lambda"; import { Buffer } from "buffer"; import { Logger } from "@aws-lambda-powertools/logger"; const logger = new Logger({ logLevel: "INFO", serviceName: "kinesis-stream-handler-sample", }); export const functionHandler: KinesisStreamHandler = async ( event: KinesisStreamEvent, context: Context ): Promise<void> => { for (const record of event.Records) { try { logger.info(`Processed Kinesis Event - EventID: ${record.eventID}`); const recordData = await getRecordDataAsync(record.kinesis); logger.info(`Record Data: ${recordData}`); // TODO: Do interesting work based on the new data } catch (err) { logger.error(`An error occurred ${err}`); throw err; } logger.info(`Successfully processed ${event.Records.length} records.`); } }; async function getRecordDataAsync( payload: KinesisStreamRecordPayload ): Promise<string> { var data = Buffer.from(payload.data, "base64").toString("utf-8"); await Promise.resolve(1); //Placeholder for actual async work return data; }

以下代码示例演示如何实现 Lambda 函数,该函数接收通过从 DynamoDB 流接收记录而触发的事件。该函数检索 DynamoDB 有效负载,并记录下记录内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用一个 DynamoDB 事件。 JavaScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { console.log(JSON.stringify(event, null, 2)); event.Records.forEach(record => { logDynamoDBRecord(record); }); }; const logDynamoDBRecord = (record) => { console.log(record.eventID); console.log(record.eventName); console.log(`DynamoDB Record: ${JSON.stringify(record.dynamodb)}`); };

使用 Lambda 使用一个 DynamoDB 事件。 TypeScript

export const handler = async (event, context) => { console.log(JSON.stringify(event, null, 2)); event.Records.forEach(record => { logDynamoDBRecord(record); }); } const logDynamoDBRecord = (record) => { console.log(record.eventID); console.log(record.eventName); console.log(`DynamoDB Record: ${JSON.stringify(record.dynamodb)}`); };

以下代码示例说明如何实现一个 Lambda 函数,该函数接收通过从 DocumentDB 更改流接收记录而触发的事件。该函数检索 DocumentDB 有效负载,并记录下记录内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用亚马逊 DocumentDB 事件。 JavaScript

console.log('Loading function'); exports.handler = async (event, context) => { event.events.forEach(record => { logDocumentDBEvent(record); }); return 'OK'; }; const logDocumentDBEvent = (record) => { console.log('Operation type: ' + record.event.operationType); console.log('db: ' + record.event.ns.db); console.log('collection: ' + record.event.ns.coll); console.log('Full document:', JSON.stringify(record.event.fullDocument, null, 2)); };

使用 Lambda 使用亚马逊文档数据库事件 TypeScript

import { DocumentDBEventRecord, DocumentDBEventSubscriptionContext } from 'aws-lambda'; console.log('Loading function'); export const handler = async ( event: DocumentDBEventSubscriptionContext, context: any ): Promise<string> => { event.events.forEach((record: DocumentDBEventRecord) => { logDocumentDBEvent(record); }); return 'OK'; }; const logDocumentDBEvent = (record: DocumentDBEventRecord): void => { console.log('Operation type: ' + record.event.operationType); console.log('db: ' + record.event.ns.db); console.log('collection: ' + record.event.ns.coll); console.log('Full document:', JSON.stringify(record.event.fullDocument, null, 2)); };

以下代码示例说明如何实现 Lambda 函数,该函数接收通过从 Ama MSK zon 集群接收记录而触发的事件。该函数检索MSK有效载荷并记录记录内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用亚马逊MSK活动。 JavaScript

exports.handler = async (event) => { // Iterate through keys for (let key in event.records) { console.log('Key: ', key) // Iterate through records event.records[key].map((record) => { console.log('Record: ', record) // Decode base64 const msg = Buffer.from(record.value, 'base64').toString() console.log('Message:', msg) }) } }

以下代码示例展示了如何实现一个 Lambda 函数,该函数接收通过将对象上传到 S3 桶而触发的事件。该函数从事件参数中检索 S3 存储桶名称和对象密钥,并调用 Amazon S3 API 来检索和记录对象的内容类型。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用 S3 事件。 JavaScript

import { S3Client, HeadObjectCommand } from "@aws-sdk/client-s3"; const client = new S3Client(); export const handler = async (event, context) => { // Get the object from the event and show its content type const bucket = event.Records[0].s3.bucket.name; const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); try { const { ContentType } = await client.send(new HeadObjectCommand({ Bucket: bucket, Key: key, })); console.log('CONTENT TYPE:', ContentType); return ContentType; } catch (err) { console.log(err); const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; console.log(message); throw new Error(message); } };

使用 Lambda 使用 S3 事件。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { S3Event } from 'aws-lambda'; import { S3Client, HeadObjectCommand } from '@aws-sdk/client-s3'; const s3 = new S3Client({ region: process.env.AWS_REGION }); export const handler = async (event: S3Event): Promise<string | undefined> => { // Get the object from the event and show its content type const bucket = event.Records[0].s3.bucket.name; const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); const params = { Bucket: bucket, Key: key, }; try { const { ContentType } = await s3.send(new HeadObjectCommand(params)); console.log('CONTENT TYPE:', ContentType); return ContentType; } catch (err) { console.log(err); const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; console.log(message); throw new Error(message); } };

以下代码示例说明如何实现一个 Lambda 函数,该函数接收通过接收来自主题的消息而触发的事件。SNS该函数从事件参数检索消息并记录每条消息的内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用一个SNS事件。 JavaScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const record of event.Records) { await processMessageAsync(record); } console.info("done"); }; async function processMessageAsync(record) { try { const message = JSON.stringify(record.Sns.Message); console.log(`Processed message ${message}`); await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

使用 Lambda 使用一个SNS事件。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { SNSEvent, Context, SNSHandler, SNSEventRecord } from "aws-lambda"; export const functionHandler: SNSHandler = async ( event: SNSEvent, context: Context ): Promise<void> => { for (const record of event.Records) { await processMessageAsync(record); } console.info("done"); }; async function processMessageAsync(record: SNSEventRecord): Promise<any> { try { const message: string = JSON.stringify(record.Sns.Message); console.log(`Processed message ${message}`); await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

以下代码示例说明如何实现一个 Lambda 函数,该函数接收通过从队列接收消息而触发的事件。SQS该函数从事件参数检索消息并记录每条消息的内容。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 使用一个SQS事件。 JavaScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const message of event.Records) { await processMessageAsync(message); } console.info("done"); }; async function processMessageAsync(message) { try { console.log(`Processed message ${message.body}`); // TODO: Do interesting work based on the new message await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

使用 Lambda 使用一个SQS事件。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { SQSEvent, Context, SQSHandler, SQSRecord } from "aws-lambda"; export const functionHandler: SQSHandler = async ( event: SQSEvent, context: Context ): Promise<void> => { for (const message of event.Records) { await processMessageAsync(message); } console.info("done"); }; async function processMessageAsync(message: SQSRecord): Promise<any> { try { console.log(`Processed message ${message.body}`); // TODO: Do interesting work based on the new message await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

以下代码示例展示了如何为接收来自 Kinesis 流的事件的 Lambda 函数实现部分批处理响应。该函数在响应中报告批处理项目失败,并指示 Lambda 稍后重试这些消息。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

报告使用 Javascript 进行 Lambda Kinesis 批处理项目失败。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const record of event.Records) { try { console.log(`Processed Kinesis Event - EventID: ${record.eventID}`); const recordData = await getRecordDataAsync(record.kinesis); console.log(`Record Data: ${recordData}`); // TODO: Do interesting work based on the new data } catch (err) { console.error(`An error occurred ${err}`); /* Since we are working with streams, we can return the failed item immediately. Lambda will immediately begin to retry processing from this failed item onwards. */ return { batchItemFailures: [{ itemIdentifier: record.kinesis.sequenceNumber }], }; } } console.log(`Successfully processed ${event.Records.length} records.`); return { batchItemFailures: [] }; }; async function getRecordDataAsync(payload) { var data = Buffer.from(payload.data, "base64").toString("utf-8"); await Promise.resolve(1); //Placeholder for actual async work return data; }

使用 Lambda 报告 Kinesis 批处理项目失败。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { KinesisStreamEvent, Context, KinesisStreamHandler, KinesisStreamRecordPayload, KinesisStreamBatchResponse, } from "aws-lambda"; import { Buffer } from "buffer"; import { Logger } from "@aws-lambda-powertools/logger"; const logger = new Logger({ logLevel: "INFO", serviceName: "kinesis-stream-handler-sample", }); export const functionHandler: KinesisStreamHandler = async ( event: KinesisStreamEvent, context: Context ): Promise<KinesisStreamBatchResponse> => { for (const record of event.Records) { try { logger.info(`Processed Kinesis Event - EventID: ${record.eventID}`); const recordData = await getRecordDataAsync(record.kinesis); logger.info(`Record Data: ${recordData}`); // TODO: Do interesting work based on the new data } catch (err) { logger.error(`An error occurred ${err}`); /* Since we are working with streams, we can return the failed item immediately. Lambda will immediately begin to retry processing from this failed item onwards. */ return { batchItemFailures: [{ itemIdentifier: record.kinesis.sequenceNumber }], }; } } logger.info(`Successfully processed ${event.Records.length} records.`); return { batchItemFailures: [] }; }; async function getRecordDataAsync( payload: KinesisStreamRecordPayload ): Promise<string> { var data = Buffer.from(payload.data, "base64").toString("utf-8"); await Promise.resolve(1); //Placeholder for actual async work return data; }

以下代码示例演示如何为接收来自 DynamoDB 流的事件的 Lambda 函数实现部分批量响应。该函数在响应中报告批处理项目失败,并指示 Lambda 稍后重试这些消息。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 报告 DynamoDB 批处理项目失败。 JavaScript

export const handler = async (event) => { const records = event.Records; let curRecordSequenceNumber = ""; for (const record of records) { try { // Process your record curRecordSequenceNumber = record.dynamodb.SequenceNumber; } catch (e) { // Return failed record's sequence number return { batchItemFailures: [{ itemIdentifier: curRecordSequenceNumber }] }; } } return { batchItemFailures: [] }; };

使用 Lambda 报告 DynamoDB 批处理项目失败。 TypeScript

import { DynamoDBBatchResponse, DynamoDBBatchItemFailure, DynamoDBStreamEvent, } from "aws-lambda"; export const handler = async ( event: DynamoDBStreamEvent ): Promise<DynamoDBBatchResponse> => { const batchItemFailures: DynamoDBBatchItemFailure[] = []; let curRecordSequenceNumber; for (const record of event.Records) { curRecordSequenceNumber = record.dynamodb?.SequenceNumber; if (curRecordSequenceNumber) { batchItemFailures.push({ itemIdentifier: curRecordSequenceNumber, }); } } return { batchItemFailures: batchItemFailures }; };

以下代码示例说明如何为从队列接收事件的 Lambda 函数实现部分批量响应。SQS该函数在响应中报告批处理项目失败,并指示 Lambda 稍后重试这些消息。

SDK对于 JavaScript (v3)
注意

还有更多相关信息 GitHub。在无服务器示例存储库中查找完整示例,并了解如何进行设置和运行。

使用 Lambda 报告SQS批量项目失败。 JavaScript

// Node.js 20.x Lambda runtime, AWS SDK for Javascript V3 export const handler = async (event, context) => { const batchItemFailures = []; for (const record of event.Records) { try { await processMessageAsync(record, context); } catch (error) { batchItemFailures.push({ itemIdentifier: record.messageId }); } } return { batchItemFailures }; }; async function processMessageAsync(record, context) { if (record.body && record.body.includes("error")) { throw new Error("There is an error in the SQS Message."); } console.log(`Processed message: ${record.body}`); }

使用 Lambda 报告SQS批量项目失败。 TypeScript

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { SQSEvent, SQSBatchResponse, Context, SQSBatchItemFailure, SQSRecord } from 'aws-lambda'; export const handler = async (event: SQSEvent, context: Context): Promise<SQSBatchResponse> => { const batchItemFailures: SQSBatchItemFailure[] = []; for (const record of event.Records) { try { await processMessageAsync(record); } catch (error) { batchItemFailures.push({ itemIdentifier: record.messageId }); } } return {batchItemFailures: batchItemFailures}; }; async function processMessageAsync(record: SQSRecord): Promise<void> { if (record.body && record.body.includes("error")) { throw new Error('There is an error in the SQS Message.'); } console.log(`Processed message ${record.body}`); }