aws-apigateway: GatewayResponse needs replacement when rest api gets redeployed
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
Whenever the deployment updates occur for RestApi, the existing GatewayResponse resources are not added back to the API's gateway responses post new deployment, thus triggering responses with the default response template (`{"message":$context.error.messageString}`) instead of the custom ones.
### Expected Behavior
Responses need to be from custom response template defined via the **unchanged** GatewayResponse CDK resources.
### Current Behavior
Getting responses with the default response template (`{"message":$context.error.messageString}`) instead in spite of GatewayResponse resources in CDK referring to the right RestApi.
### Reproduction Steps
```
export class ApiGwResponseBugStack extends cdk.Stack {
readonly api: apigateway.SpecRestApi;
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.api = new apigateway.SpecRestApi(this, 'pets-api', {
apiDefinition: apigateway.ApiDefinition.fromInline(
JSON.parse(readFileSync("config/openapi.json", 'utf8'))
)
});
Object.values(ResponseType).map((responseType) => {
this.addCustomAPIGWResponse(responseType);
});
}
addCustomAPIGWResponse(responseType: ResponseType) {
const gatewayResponseProps: GatewayResponseProps = {
restApi: this.api,
type: responseType,
templates: {
'application/json': JSON.stringify({
errorCode: '$context.error.responseType',
errorMessage: '$context.error.validationErrorString',
}),
},
};
const gatewayResponse = this.api.addGatewayResponse(
`CustomGatewayResponse_${responseType.responseType}`,
gatewayResponseProps,
);
}
}
```
### Possible Solution
**Potential Cause**
RestApi Deployment depend on GatewayResponse resources but not the other way around. However adding RestApi Deployment on the GatewayResponse's "Depends On" list would cause circular dependency. Could this be the cause?
```
"petsapiDeploymentDD4F692C0df298629840e6883720c9571f342009": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"Description": "Automatically created by the RestApi construct",
"RestApiId": {
"Ref": "petsapi924A35D8"
}
},
"DependsOn": [
"petsapiCustomGatewayResponseACCESSDENIED28E6B5D1",
"petsapiCustomGatewayResponseAPICONFIGURATIONERROR9330A1F8",
...
],
"Metadata": {
"aws:cdk:path": "ApiGwResponseBugStack/pets-api/Deployment/Resource"
}
..................
..................
"petsapiCustomGatewayResponseACCESSDENIED28E6B5D1": {
"Type": "AWS::ApiGateway::GatewayResponse",
"Properties": {
"ResponseTemplates": {
"application/json": "{\"errorCode\":\"$context.error.responseType\",\"errorMessage\":\"$context.error.validationErrorString\"}"
},
"ResponseType": "ACCESS_DENIED",
"RestApiId": {
"Ref": "petsapi924A35D8"
}
},
"Metadata": {
"aws:cdk:path": "ApiGwResponseBugStack/pets-api/CustomGatewayResponse_ACCESS_DENIED/Resource"
}
```
Does this mean it is expected to replace GatewayResponse resources (via salting the id field) whenever rest api gets redeployed? Or is there other means to solve this problem?
**Workaround**
```
const gatewayResponse = this.api.addGatewayResponse(
`CustomGatewayResponse_${responseType.responseType}_${String(Date.now())}`,
gatewayResponseProps,
);
```
### Additional Information/Context
With the workaround above, due to salting the id with timestamp, the GatewayResponse resources get replaced (destroyed & recreated) for every `cdk deploy` (regardless of changes to the custom response props).
However, since the logicalId for Deployment doesn't include GatewayResponse ID, the workaround would not trigger a deployment. (ref: https://github.com/aws/aws-cdk/pull/11068/files/619d94cd0b49ea1eefe3617949975cecb33f7ffa)
So I would like to know if there is a way to avoid the unintended CDK resource replacements.
### CDK CLI Version
2.118.0 (build a40f2ec)
### Framework Version
_No response_
### Node.js Version
v16.11.1
### OS
Linux
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start by tracing the apigateway SpecRestApi, addGatewayResponse, and Deployment entry points, then review the behavior referenced in pull request 11068. Reproduce the deployment with unchanged GatewayResponse resources and inspect the synthesized dependencies. Done means redeployments preserve custom responses without replacing unchanged resources or creating a circular dependency.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100