英文:
Appsync/CDK: Add a DynamoDB table name as a parameter to a lambda resolver
问题
In Typescript CDK 2,我正在创建一个AppSync实例和一个DynamoDB表。我想修改解析器的粘合部分,以便AppSync将表名作为单独的参数传递给Lambda解析器。通过这种方式,我可以为不同的租户生成不同的堆栈,并确保每个租户通过Lambda与他们自己的DynamoDB表进行通信。
目前,我使用以下代码来设置解析器:
requestMappingTemplate: appsync.MappingTemplate.lambdaRequest(),
我看到这个函数将lambdaRequest的payload参数设置为默认参数[代码链接]:
'$util.toJson($ctx)'
由于CDK在调用lambdaRequest时可以访问表名,所以是否有一种简单的方式来修改lambdaRequest的payload参数,以添加表名呢?
英文:
In Typescript CDK 2 I am creating an AppSync instance and a DynamoDB table. I would like to modify the resolver glue so that AppSync passes the table name to the lambda resolver as a separate argument. In this manner I can generate different stacks for different tenants and be assured each tenant communicates with their own DynamoDB table via a lambda.
Currently, I use the following to set up the resolver:
requestMappingTemplate: appsync.MappingTemplate.lambdaRequest(),
and I see that that function is setting the payload argument of lambdaRequest to the default argument [code link]:
'$util.toJson($ctx)'
Since CdK has access to the table name at the moment lambdaRequest is called is there a simple variation of the payload argument to lambdaRequest that adds in the table name?
答案1
得分: 0
I ended up replacing the appsync.MappingTemplate.lambdaRequest()
function with my own function that generates VTL for this purpose.
In my CDK directory, under lib/vtl_templates
, I created a file generic_request.vtl
with the following contents.
{
"version": "2018-05-29",
"payload": {
"info": { "fieldName": "${fieldName}" },
"fieldName": "${fieldName}",
"tableName": "${tableName}",
"arguments": $util.toJson($ctx.arguments)
}
}
A typescript function in the CDK source parses this file into a template object, performing variable interpolation.
function createLambdaRequest(
fieldName: string,
tableName: string
): appsync.MappingTemplate {
const vtl_template_string = readFileSync(
"./lib/vtl_templates/generic_request.vtl"
).toString();
const vtl_string = eval("`" + vtl_template_string + "`");
return appsync.MappingTemplate.fromString(vtl_string);
}
Finally, I attached the MappingTemplate object to the DynamoDB resolver like so.
lambdaDS.createResolver(resolverName, {
typeName: "Query",
fieldName: fieldName,
requestMappingTemplate: createLambdaRequest(
fieldName,
dynamodbTable.tableName
),
responseMappingTemplate: appsync.MappingTemplate.lambdaResult(),
});
Running `cdk diff --all` provides a nice way to inspect the result.
<details>
<summary>英文:</summary>
I ended up replacing the `appsync.MappingTemplate.lambdaRequest()` function with my own function that generates VTL for this purpose.
In my CDK directory, under `lib/vtl_templates`, I created a file `generic_request.vtl` with the following contents.
```vtl
{
"version": "2018-05-29",
"payload": {
"info": { "fieldName": "${fieldName}" },
"fieldName": "${fieldName}",
"tableName": "${tableName}",
"arguments": $util.toJson($ctx.arguments)
}
}
A typescript function in the CDK source parses this file into a template object, performing variable interpolation.
function createLambdaRequest(
fieldName: string,
tableName: string
): appsync.MappingTemplate {
const vtl_template_string = readFileSync(
"./lib/vtl_templates/generic_request.vtl"
).toString();
const vtl_string = eval("`" + vtl_template_string + "`");
return appsync.MappingTemplate.fromString(vtl_string);
}
Finally, I attached the MappingTemplate object to the DynamoDB resolver like so.
lambdaDS.createResolver(resolverName, {
typeName: "Query",
fieldName: fieldName,
requestMappingTemplate: createLambdaRequest(
fieldName,
dynamodbTable.tableName
),
responseMappingTemplate: appsync.MappingTemplate.lambdaResult(),
});
Running cdk diff --all
provides a nice way to inspect the result.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论