aws / aws/aws-cdk-cli

(hotswap): hotswap support for API Gateway

Open
#880 1 comment 7 reactions 0 assignees View on GitHub
effort/medium feature-request p2
Dominant language
TypeScript
Stars
105
Forks
122
Avg merge
1d 17h
Merged PRs (30d)
71

Description

### Description

I'd like the CDK CLI to hotswap the following API Gateway Method constituents:
- Method `requestParameters`
- Integration `requestParameters`
- Integration `requestTemplates`
- Integration `responseTemplates`
- Method `methodResponses`

### Use Case

Development of service-to-service integrations with `AwsIntegration`, especially when using substantial VTL code.

### Proposed Solution

We should hotswap these fields so that incremental development doesn't require substantial CloudFormation waits between changes.

### Other information

Example of a non-trivial service-to-service integration:

```ts
const AMZ_JSON_1_0 = 'application/x-amz-json-1.0';
const APPLICATION_JSON = 'application/json';

const requestModel = new aws_apigateway.Model(this, 'Model', {
restApi: resource.api,
schema: {
type: aws_apigateway.JsonSchemaType.OBJECT,
properties: {
test: { type: aws_apigateway.JsonSchemaType.STRING },
env: { type: aws_apigateway.JsonSchemaType.STRING },
result: { type: [aws_apigateway.JsonSchemaType.OBJECT, aws_apigateway.JsonSchemaType.STRING] },
},
required: [
'env',
'test',
'result',
],
},
});

new aws_apigateway.Method(this, 'PostMethod', {
httpMethod: 'POST',
resource: resource,
options: {
methodResponses: [{ statusCode: '200' }],
requestModels: {
[APPLICATION_JSON]: requestModel,
},
requestValidatorOptions: {
validateRequestBody: true,
},
},
integration: new aws_apigateway.AwsIntegration({
service: 'dynamodb',
action: 'PutItem',
options: {
credentialsRole,
requestTemplates: {
[APPLICATION_JSON]: [
"#set ($env = $input.path('$.env'))",
"#set ($test = $input.path('$.test'))",
"#set ($timeId = $context.requestTimeEpoch + '#' + $context.requestId)",
JSON.stringify({
TableName: table.tableName,
Item: {
// Test results in an environment by date
PK: { S: 'ENV#$util.escapeJavaScript($env)' },
SK: { S: 'TEST#$util.escapeJavaScript($test)#$timeId' },
// Test results across environments by date
GSI1PK: { S: 'TEST#$util.escapeJavaScript($test)' },
GSI1SK: { S: 'ENV#$util.escapeJavaScript($env)#$timeId' },
// Data
env: { S: '$util.escapeJavaScript($env)' },
test: { S: '$util.escapeJavaScript($test)' },
result: { S: "$util.escapeJavaScript($input.json('$.result'))" },
},
}),
].join('\n'),
},
passthroughBehavior: aws_apigateway.PassthroughBehavior.WHEN_NO_MATCH,
integrationResponses: [{
statusCode: '200',
responseTemplates: {
[AMZ_JSON_1_0]: JSON.stringify({
requestId: '$context.requestId',
}),
},
}],
},
}),
});

new aws_apigateway.Method(this, 'GetByEnvMethod', {
httpMethod: 'GET',
resource: resource,
options: {
methodResponses: [{
statusCode: '200',
}],
requestParameters: {
'method.request.path.env': true,
},
},
integration: new aws_apigateway.AwsIntegration({
service: 'dynamodb',
action: 'Query',
options: {
credentialsRole,
requestParameters: {
'integration.request.path.env': 'method.request.path.env',
},
requestTemplates: {
[APPLICATION_JSON]: [
"#set ($env = $input.params('env'))",
'#set ($limit = 2)',
JSON.stringify({
TableName: table.tableName,
Limit: '$limit',
KeyConditionExpression: 'PK = :PK',
ExpressionAttributeValues: {
':PK': { S: 'ENV#$util.escapeJavaScript($env)' },
},
}),
].join('\n'),
},
passthroughBehavior: aws_apigateway.PassthroughBehavior.WHEN_NO_MATCH,
integrationResponses: [{
statusCode: '200',
responseTemplates: {
[AMZ_JSON_1_0]: [
"#set($root = $input.path('$'))",
'{',
// eslint-disable-next-line quotes
` "Count": $root.Count,`,
' "Results": [',
'#foreach($item in $root.Items)',
'#set($env = $item.env.S)',
'#set($test = $item.test.S)',
'#set($result = $item.result.S)',
' {',
' "env": "$util.escapeJavaScript($env)",',
' "test": "$util.escapeJavaScript($test)",',
' "result": $result', // Provide the JSON directly.
' }#if($foreach.hasNext),#end',
'#end',
'',
' ]',
'}',
].join('\n'),
},
}],
},
}),
});
```

### Acknowledge

- [ ] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.