AWS CDK 事件桥接器和 api 网关 AWS 示例不起作用

问题描述

我正在按照此处的说明设置事件桥:https://eventbus-cdk.workshop.aws/en/04-api-gateway-service-integrations/01-rest-api/rest-apis.html

根据错误信息,错误来自这行代码:languageResource.addMethod("POST",new apigw.Integration({

我不确定是什么导致了这个问题,因为这是 AWS 提供的一个例子,应该可以工作,但它没有。

我可以构建它,但它在 cdk deploy 上失败并出现以下错误

CREATE_Failed        | AWS::ApiGateway::Method           | MyRestAPI/Default/{language}/POST (MyRestAPIlanguagePOSTB787D51A) Invalid Resource identifier specified (Service: AmazonApiGateway; Status Code: 404; Error Code: NotFoundException;

代码如下:

    const myLambda = new lambda.Function(this,"MyEventProcessor",{
  code: new lambda.InlineCode("def main(event,context):\n\tprint(event)\n\treturn {'statusCode': 200,'body': 'Hello,World'}"),handler: "index.main",runtime: lambda.Runtime.PYTHON_3_7
})

  
const bus = new events.EventBus(this,`pwm-${this.stage}-MdpEventBus`)
new cdk.CfnOutput(this,"PwmMdpEventBus",{value: bus.eventBusName})

new events.Rule(this,`PwmMdpEventBusRule`,{
  eventBus: bus,eventPattern: {source: [`com.amazon.alexa.english`]},targets: [new targets.LambdaFunction(myLambda)]
})

const apigwRole = new iam.Role(this,"MYAPIGWRole",{
  assumedBy: new iam.ServicePrincipal("apigateway"),inlinePolicies: {
    "putEvents": new iam.PolicyDocument({
      statements: [new iam.PolicyStatement({
        actions: ["events:PutEvents"],resources: [bus.eventBusArn]
      })]
    })
  }
});

const options = {
  credentialsRole: apigwRole,requestParameters: {
    "integration.request.header.X-Amz-Target": "'AWSEvents.PutEvents'","integration.request.header.Content-Type": "'application/x-amz-json-1.1'"
  },requestTemplates: {
    "application/json": `#set($language=$input.params('language'))\n{"Entries": [{"Source": "com.amazon.alexa.$language","Detail": "$util.escapeJavaScript($input.body)","Resources": ["resource1","resource2"],"DetailType": "myDetailType","EventBusName": "${bus.eventBusName}"}]}`
  },integrationResponses: [{
    statusCode: "200",responseTemplates: {
      "application/json": ""
    }
  }]
}

const myRestAPI = new apigw.RestApi(this,"MyRestAPI");

const languageResource = myRestAPI.root.addResource("{language}");

languageResource.addMethod("POST",new apigw.Integration({
  type: apigw.IntegrationType.AWS,uri: `arn:aws:apigateway:${cdk.Aws.REGION}:events:path//`,integrationHttpMethod: "POST",options: options,}),{
  methodResponses: [{
      statusCode: "200"
    }],requestModels: {"application/json": model.getModel(this,myRestAPI) },requestValidator: new apigw.RequestValidator(this,"myValidator",{
    restApi: myRestAPI,validateRequestBody: true
  })
})

解决方法

在 AWS 示例中,他们将您的代码封装在里面

export class MyCdkAppStack extends cdk.Stack {
...
}

您是否缺少这种封装?我注意到您的示例代码没有包含它。因为当您执行 const myRestAPI = new apigw.RestApi(this,"MyRestAPI"); 时,this 应该引用 MyCdkAppStack 实例。