You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在TypeScript CDK 2中配置AppSync将DynamoDB表名传入Lambda解析器

在TypeScript CDK 2中给AppSync Lambda解析器请求添加DynamoDB表名

核心思路

默认的appsync.MappingTemplate.lambdaRequest()生成的映射模板仅传递$ctx的JSON内容,要添加表名,需要自定义VTL请求模板,并通过CDK将表名注入模板中,这是最直接简便的实现方式。

具体实现步骤

1. 创建租户专属DynamoDB表

多租户场景下每个栈对应一个独立表,先完成表的定义:

import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class TenantStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // 租户专属DynamoDB表
    const tenantTable = new dynamodb.Table(this, 'TenantTable', {
      partitionKey: { name: 'tenantId', type: dynamodb.AttributeType.STRING },
      sortKey: { name: 'itemId', type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
    });
  }
}

2. 构建自定义Lambda请求映射模板

通过appsync.MappingTemplate.fromString()结合Fn.sub(),将表名注入到VTL模板中,保留原$ctx内容的同时新增tableName字段:

import * as appsync from 'aws-cdk-lib/aws-appsync';
import { Fn } from 'aws-cdk-lib';

// 假设已创建AppSync API和Lambda数据源
const api = new appsync.GraphqlApi(this, 'TenantApi', {
  name: 'TenantApi',
  schema: appsync.SchemaFile.fromAsset('schema.graphql'),
});

const lambdaDataSource = api.addLambdaDataSource('TenantLambdaDs', tenantLambdaFunction);

// 自定义请求模板:在payload中同时传递原context和表名
const customLambdaRequestTemplate = appsync.MappingTemplate.fromString(Fn.sub(`
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "context": \$util.toJson(\$ctx),
    "tableName": "\${tableName}"
  }
}
`, { tableName: tenantTable.tableName }));

3. 配置解析器使用自定义模板

替换默认的lambdaRequest(),将自定义模板绑定到目标解析器:

// 为Query类型的getItem字段配置解析器
api.addResolver('GetItemResolver', {
  typeName: 'Query',
  fieldName: 'getItem',
  dataSource: lambdaDataSource,
  requestMappingTemplate: customLambdaRequestTemplate,
  responseMappingTemplate: appsync.MappingTemplate.lambdaResult(), // 保留默认响应模板
});

Lambda端接收参数

Lambda函数可直接从事件的payload中获取表名,无需额外配置环境变量:

import * as AWS from 'aws-sdk';
const dynamo = new AWS.DynamoDB.DocumentClient();

export const handler = async (event: any) => {
  const { tableName, context } = event;
  // 使用tableName操作对应租户的DynamoDB表
  const result = await dynamo.get({
    TableName: tableName,
    Key: {
      tenantId: context.arguments.tenantId,
      itemId: context.arguments.itemId,
    },
  }).promise();
  return result.Item;
};

关键注意事项

  • VTL中的$符号在TypeScript模板字符串中需要用\$转义,避免被当作模板变量解析。
  • 通过Fn.sub()注入表名,能确保CDK部署时自动替换为带CloudFormation后缀的实际表名。
  • 该方式无需依赖Lambda环境变量,表名随请求直接传递,更适配多租户栈的独立部署需求。

内容的提问来源于stack exchange,提问作者Setjmp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:47:35