Aws lambda AWS CDK将API网关URL传递到同一堆栈中的静态站点

Aws lambda AWS CDK将API网关URL传递到同一堆栈中的静态站点,aws-lambda,aws-api-gateway,aws-cdk,Aws Lambda,Aws Api Gateway,Aws Cdk,我试图在单个堆栈中部署S3静态网站和API网关/lambda S3静态站点中的javascript调用lambda来填充HTML列表,但它需要知道lambda集成的API网关URL 目前,我生成了一个RestApi,如下所示 const handler = new lambda.Function(this, "TestHandler", { runtime: lambda.Runtime.NODEJS_10_X, code: lambda.Code.asset("

我试图在单个堆栈中部署S3静态网站和API网关/lambda

S3静态站点中的javascript调用lambda来填充HTML列表,但它需要知道lambda集成的API网关URL

目前,我生成了一个RestApi,如下所示

    const handler = new lambda.Function(this, "TestHandler", {
      runtime: lambda.Runtime.NODEJS_10_X,
      code: lambda.Code.asset("build/test-service"),
      handler: "index.handler",
      environment: {
      }
    });

    this.api = new apigateway.RestApi(this, "test-api", {
      restApiName: "Test Service"
    });    

    const getIntegration = new apigateway.LambdaIntegration(handler, {
      requestTemplates: { "application/json": '{ "statusCode": "200" }' }
    });

    const apiUrl = this.api.url;
但在cdk部署上,apiUrl=

“https://${Token[Token.39]}。执行api。${Token[AWS::Region.4]}.${Token[AWS::URLSuffix.1]}/${Token[Token.45]}/”

因此,在静态站点需要该值之前,不会解析/生成url

如何计算/查找/获取API网关URL并在cdk部署上更新javascript

还是有更好的方法?i、 静态javascript是否有一种优雅的方式来检索lambda api网关url


谢谢。

您正在创建lambdainintegration,但它未连接到API

要将它添加到API的根目录,请执行以下操作:this.API.root.addMethod(…),并使用它连接lambdainIntegration和API


这将为您提供一个带有URL的端点

如果您也在使用
s3部署
模块来部署您的网站,那么我可以使用当前可用的解决方案(等待更好的解决方案)。以下内容使您能够将
config.js
部署到bucket(包含堆栈中仅在部署时填充的属性),然后在运行时依赖于代码中的其他地方

内联源代码.ts
中:

//为简洁起见,已删除导入
inlineSource中的导出函数(路径:字符串,内容:字符串,选项?:AssetOptions):ISource{
返回{
绑定:(作用域:构造,上下文?:DeploymentSourceContext):SourceConfig=>{
如果(!上下文){
抛出新错误('要使用inlineSource,必须提供上下文');
}
//查找可用ID
设id=1;
while(scope.node.tryFindChild(`InlineSource${id}`){
id++;
}
const bucket=new bucket(作用域,`InlineSource${id}StagingBucket`{
removalPolicy:removalPolicy.DESTROY
});
const fn=new函数(作用域,`InlineSource${id}Lambda`{
运行时:runtime.NODEJS_12_X,
处理程序:“index.handler”,
代码:code.fromAsset('./内联lambda')
});
bucket.granteradwrite(fn);
const myProvider=new Provider(作用域,`InlineSource${id}Provider`{
奥文坦德勒:fn,
logRetention:RetentionDays.ONE_DAY//默认值为无限
});
const resource=new CustomResource(作用域,`InlineSource${id}CustomResource`,{serviceToken:myProvider.serviceToken,属性:{bucket:bucket.bucketName,路径,内容});
context.handlerRole.node.addDependency(resource);//将s3部署设置为依赖于部署的文件
grantrade(context.handlerRole);
返回{
桶:桶,
ZipoObjectKey:'index.zip'
};
},
};
}
内联lambda/index.js中(也需要在内联lambda/node_模块中安装archiver):

const aws=require('aws-sdk');
consts3=新的aws.s3({apiVersion:'2006-03-01'});
常数fs=要求('fs');
var archive=require('archiver')('zip');
exports.handler=异步函数(事件,ctx){
等待新的承诺(resolve=>fs.unlink('/tmp/index.zip',resolve));
const output=fs.createWriteStream('/tmp/index.zip');
const closed=新承诺((解决、拒绝)=>{
输出。打开('close',resolve);
输出。on('错误',拒绝);
});
归档.管道(输出);
append(event.ResourceProperties.content,{name:event.ResourceProperties.path});
archive.finalize();
等待关闭;
等待s3.upload({Bucket:event.ResourceProperties.Bucket,Key:'index.zip',Body:fs.createReadStream('/tmp/index.zip'))});
返回;
}
在构造中,使用
inlineSource

导出类TestConstruct扩展构造{
构造函数(作用域:Construct,id:string,props:any){
//设立其他资源
const source=inlineSource('config.js','exports.config={apident:'${api.attrApiEndpoint}}}');
//用于BucketDeployment
}
}
您可以将
内联lambda
移动到其他位置,但需要能够将其作为lambda的资产进行捆绑


这是通过创建一个自定义资源来实现的,该资源依赖于堆栈中的其他资源(从而允许解析属性),该资源将文件写入一个zip文件,然后将该文件存储到一个bucket中,然后提取并解压缩到部署/目标bucket中。非常复杂,但可以用当前可用的内容完成任务。

只是为了确保,您想创建一个新的api网关,然后使用url?是的,我正在研究创建一个名为config.json的S3Object,内容为{“apiurl”:!Sub“https://${restApiId}.execute api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}”但我无法在cdk部署期间获取restApiId。“稍后使用url”是指在堆栈部署的稍后阶段,我想用url值填充S3文件。@benito_h在这里查看我的答案:@Tim你能找到解决方案吗?我正在考虑用URL作为参数创建一个自定义资源,以创建该对象,但我很想知道是否有更优雅的解决方案。看到他们在解决您的问题@alex9311,我打开了一个功能请求,该请求可能更符合CDK的设想