我有一个主堆栈(共享资源)和几个工作堆栈。我的主堆栈包含一个 api 网关资源,我将其传递到工作堆栈中,工作堆栈将为其关联功能附加一个新端点到该资源。
这是代码的细分:
main-stack.ts
- 创建 api 网关资源
export class MainSlackBotStack extends cdk.Stack {
public readonly basicAuthorizerFunction: apigateway.RequestAuthorizer;
public readonly api: apigateway.RestApi;
constructor(scope: Construct, id: string, props: MainSlackBotStackProps) {
super(scope, id, props);
// create api gateway
this.api = new apigateway.RestApi(this, 'MainSlackBotApi', {
restApiName: 'MainSlackBotApi',
description: 'This service is the api gateway for the Slack Bot',
deployOptions: {
stageName: "v1",
},
defaultCorsPreflightOptions: {
allowHeaders: [
"Content-Type",
"X-Amz-Date",
"Authorization",
"X-Api-Key",
],
allowMethods: ["OPTIONS", "POST"],
allowCredentials: true,
allowOrigins: ["*"],
},
});
}
}
worker-stack.ts
- 传递 api 网关并在其上创建自己的路径/ POST 请求
// initialize main api
const mainApi = apigateway.RestApi.fromRestApiAttributes(this, `MainApi`, {
restApiId: props.apiId,
rootResourceId: props.apiRootResourceId,
});
// add api gateway endpoint for worker bot
const slackBotEndpoint = mainApi.root.addResource(`${props.namespace}`);
slackBotEndpoint.addMethod(
"POST",
new apigateway.LambdaIntegration(commandEntryFunction, {}),
{
methodResponses: [{
statusCode: '200',
responseParameters: {
'method.response.header.Content-Type': true,
'method.response.header.Access-Control-Allow-Origin': true,
},
}],
authorizer: customAuthorizerFunction,
authorizationType: apigateway.AuthorizationType.CUSTOM,
},
);
因此,大多数事情都按预期运行,API 网关已在主堆栈中成功创建,POST 请求已附加到 API 网关资源,但它们未附加到 API 网关阶段。
因此,我无法针对已部署的 API 网关阶段对工作堆栈端点附件进行任何调用。该阶段仅显示主堆栈中定义的 API 根和关联选项请求。我认为我需要针对 API 网关资源强制进行新的部署,但我似乎找不到可靠的方法来实现这一点。有人遇到过这个问题/有一个干净的解决方案吗?
这对我有用,在导入共享 API 网关的堆栈中:
# Lookup existing API Gateway based on identifiers. It so happens that
# instead of passing root resource, here, I was passing resource "v1/"
# that was setup on the shared API Gateway stack, but shouldn't impact
# what you're looking to do.
api_gateway = RestApi.from_rest_api_attributes(
self, "RestApi", rest_api_id=api_gateway_rest_api_id,
root_resource_id=v1_resource_id
)
# This step was only necessary due to the fact I wanted to attach
# endpoints to a non root resource setup on the API Gateway.
v1_resource = apigw.Resource.from_resource_attributes(
self, "V1Resource", path="/v1", resource_id=v1_resource_id,
rest_api=api_gateway
)
# Hang new endpoints/resources off that imported from existing API Gateway
customers_resource = v1_resource.add_resource("customers")
customers_resource.add_method(
"POST",
integration=apigw.LambdaIntegration(
handler=auto_insert_post_lambda.function,
integration_responses=[
apigw.IntegrationResponse(
status_code="200",
response_parameters={
"method.response.header.Content-Type": "'application/json'"
},
)
],
),
method_responses=[
apigw.MethodResponse(
status_code="200",
response_parameters={"method.response.header.Content-Type": True}
)
],
authorization_type=apigw.AuthorizationType.CUSTOM,
authorizer=self.some_lambda_authorizer,
)
# Force API deployment with every `cdk deploy` by creating new/unique
# deployment ID (can potentially revisit). Reference existing default
# "prod" stage on shared API Gateway instance.
deployment = apigw.Deployment(
self, f"Deployment-{datetime.now()}", api=api_gateway, stage_name="prod"
)
# Get existing stage from shared API Gateway, associate with deployment.
existing_stage = apigw.Stage.from_stage_attributes(
self, "ExistingStage", stage_name="prod", rest_api=api_gateway
)
existing_stage.deployment = deployment
这样,该堆栈的端点就正确附加到现有共享资源“v1”并部署到现有“prod”阶段。