Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(apigateway): Add LambdaIntegrationOptions to LambdaRestApi #17065

Merged
merged 5 commits into from
Jun 22, 2022

Conversation

laurelmay
Copy link
Contributor

This adds an integrationOptions field to the LambdaRestApiProps and ensures that proxy cannot be set differently from the base proxy flag (but discourages setting it at all). This will allow setting the cacheKeyParameters, allowTestInvoke, and vpcLink configuration fields without having to fall back to using a regular RestApi.

Some of this is inspired by #12004 and its review comments, which was closed earlier this year due to inactivity.

Resolves: #3269


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@gitpod-io
Copy link

gitpod-io bot commented Oct 20, 2021

@github-actions github-actions bot added the @aws-cdk/aws-apigateway Related to Amazon API Gateway label Oct 20, 2021
@nija-at nija-at added effort/small Small work item – less than a day of effort p2 labels Nov 5, 2021
@nija-at nija-at removed their assignment Nov 5, 2021
@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch from 643796e to 87e3a45 Compare November 8, 2021 20:51
@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch 3 times, most recently from a6e655c to c7f8a77 Compare December 1, 2021 22:19
@rix0rrr rix0rrr added feature-request A feature should be added or improved. p2 and removed p2 @aws-cdk/aws-apigateway Related to Amazon API Gateway effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. labels Mar 4, 2022
@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch 2 times, most recently from 2714a44 to 1ff28a7 Compare March 31, 2022 03:45
@laurelmay
Copy link
Contributor Author

Turns out apparently API Gateway doesn't allow the proxy key as a CacheKeyParameter. The same behavior can be seen in the console. The PR has been updated to primarily focus on timeout instead of proxy. It doesn't seem to be a limitation of this design since the same behavior can be replicated using LambdaIntegration and RestApi separately (and in the console). But for completeness on the change here, the relevant event details from CloudTrail are:

Event Information

    "eventSource": "apigateway.amazonaws.com",
    "eventName": "UpdateIntegration",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "AWS Internal",
    "userAgent": "AWS Internal",
    "errorCode": "BadRequestException",
    "errorMessage": "Invalid cache key parameter specified",
    "requestParameters": {
        "updateIntegrationInput": {
            "patchOperations": [
                {
                    "path": "/cacheKeyParameters/method.request.path.proxy",
                    "op": "add"
                }
            ]
        },
        "restApiId": "hwnay7i82b",
        "resourceId": "7xtf1y",
        "httpMethod": "ANY",
        "template": false
    },
    

@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch from 1ff28a7 to 31c3a42 Compare March 31, 2022 04:33
Copy link
Contributor

@comcalvi comcalvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just one minor question.

@@ -1,6 +1,6 @@
// Fixture with packages imported, but nothing else
import { Construct } from 'constructs';
import { Stack } from '@aws-cdk/core';
import { Duration, Stack } from '@aws-cdk/core';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we add the Duration import here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be necessary based on the changes I also made to README.md. I got a build failure without it since jsii-rosetta couldn't find Duration (if I interpreted the error message correctly). I guess it might be possible to choose another possible integration example but that might still require another import.

@comcalvi comcalvi self-assigned this Apr 5, 2022
Copy link
Contributor

@comcalvi comcalvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking pretty good, but there's a few small issues I'd like to see resolved. Please fix the merge conflicts as well, they're preventing our usual automation from running.

packages/@aws-cdk/aws-apigateway/lib/lambda-api.ts Outdated Show resolved Hide resolved
}

const app = new App();
new LambdaApiIntegrationOptionsStack(app);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a newline to the end of this file.

proxy: false,
integrationOptions: {},
})).not.toThrow();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we remove this blank line?

Comment on lines 125 to 126
Note that `proxy: false` may not be specified in the `integrationOptions`
and must be specified directly in `props`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this only proxy: false and not proxy?

*
* @default - see defaults defined in {@link LambdaIntegrationOptions}.
*/
readonly integrationOptions?: LambdaIntegrationOptions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should explain the interaction between integrationOptions.proxy and props.proxy here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably no longer necessary

throw new Error('Cannot specify "defaultIntegration" since Lambda integration is automatically defined');
}
// Forbid setting `integrationOptions.proxy = false` unless `proxy = false`
if (props.integrationOptions?.proxy !== undefined && props.integrationOptions?.proxy !== (props?.proxy ?? true)) {
throw new Error('Cannot specify "props.integrationOptions.proxy". Instead use "props.proxy".');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we change this message to reflect the precise behavior of this interaction?

throw new Error('Cannot specify "defaultIntegration" since Lambda integration is automatically defined');
}
// Forbid setting `integrationOptions.proxy = false` unless `proxy = false`
if (props.integrationOptions?.proxy !== undefined && props.integrationOptions?.proxy !== (props?.proxy ?? true)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We reference props.integrationOptions several times. Could we extract this to a local variable, integrationOptions?

throw new Error('Cannot specify "defaultIntegration" since Lambda integration is automatically defined');
}
// Forbid setting `integrationOptions.proxy = false` unless `proxy = false`
Copy link
Contributor

@comcalvi comcalvi Apr 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on the line above should be more specific about this behavior, as well as the reasoning behind why this is desirable. Ideally this would be written with positive terms, instead of the currently used negative. I don't understand the desired interaction between integrationOptions.proxy and proxy.

Comment on lines 319 to 325
expect(() => new apigw.LambdaRestApi(stack, 'lambda-rest-api2', {
handler,
proxy: false,
integrationOptions: {
proxy: false,
},
})).not.toThrow();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work? The readme change has this:

Note that `proxy: false` may not be specified in the `integrationOptions`
and must be specified directly in `props`.

same goes everywhere else with proxy: false in these tests.

throw new Error('Cannot specify "defaultIntegration" since Lambda integration is automatically defined');
}
// Forbid setting `integrationOptions.proxy = false` unless `proxy = false`
if (props.integrationOptions?.proxy !== undefined && props.integrationOptions?.proxy !== (props?.proxy ?? true)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please simplify this if as well, it's very complicated right now.

I think it should be broken apart like this:

     if (props.integrationOptions?.proxy !== undefined) { 
       if (props.integrationOptions.proxy !== (props?.proxy ?? true)) { ...
         // ...
       }
     }

and I think the props?.proxy ?? true should be extracted into a variable with a name that describes what that part of the expression represents.

@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch from 31c3a42 to a561d12 Compare April 8, 2022 01:16
@mergify mergify bot dismissed comcalvi’s stale review April 8, 2022 01:17

Pull request has been modified.

@laurelmay
Copy link
Contributor Author

@comcalvi Thanks for the review feedback! As I was working on implementing changes based on the feedback, I realized that the proxy attributes of LambdaRestApiProps and LambdaIntegrationOptions have different meanings. LambdaRestApiProps.proxy is "should this create a {proxy+} route" and LambdaIntegrationOptions.proxy is "should this create an API Gateway Lambda Proxy integration" which I misunderstood in the initial implementation.

There should be no reason to forbid LambdaIntegrationOptions.proxy, because per https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html,

Greedy path variables, ANY methods, and proxy integration types are independent features, although they are commonly used together. You can configure a specific HTTP method on a greedy resource or apply non-proxy integration types to a proxy resource.

I think forbidding anything around props.integrationOptions.proxy was based around my understanding of #12004 but realizing the different meaning of the two proxy flags and the capabilities of API Gateway, I think removing any prohibitions on the value(s) of either is best since one if for {proxy+} paths and the other is for AWS_PROXY-type integrations (and it's possible to support one, both, or neither).

@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch from a561d12 to a751a41 Compare April 8, 2022 01:22
@laurelmay laurelmay force-pushed the lambdarestapi-lambdaintegrationoptions branch from a751a41 to 9b07f25 Compare May 6, 2022 03:09
comcalvi
comcalvi previously approved these changes Jun 15, 2022
@mergify
Copy link
Contributor

mergify bot commented Jun 15, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@comcalvi comcalvi added the pr/do-not-merge This PR should not be merged at this time. label Jun 15, 2022
@comcalvi comcalvi changed the base branch from v1-main to main June 15, 2022 00:04
@comcalvi comcalvi removed the pr/do-not-merge This PR should not be merged at this time. label Jun 15, 2022
@mergify
Copy link
Contributor

mergify bot commented Jun 15, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot dismissed comcalvi’s stale review June 17, 2022 19:59

Pull request has been modified.

@mergify
Copy link
Contributor

mergify bot commented Jun 22, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 31b7e70
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit b117469 into aws:main Jun 22, 2022
@mergify
Copy link
Contributor

mergify bot commented Jun 22, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

daschaa pushed a commit to daschaa/aws-cdk that referenced this pull request Jul 9, 2022
…17065)

This adds an `integrationOptions` field to the `LambdaRestApiProps` and ensures that `proxy` cannot be set differently from the base `proxy` flag (but discourages setting it at all). This will allow setting the `cacheKeyParameters`, `allowTestInvoke`, and `vpcLink` configuration fields without having to fall back to using a regular `RestApi`.

Some of this is inspired by aws#12004 and its review comments, which was closed earlier this year due to inactivity.

Resolves: aws#3269

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ApiGateway LambdaRestApi doesn't allow overriding default integration properties
5 participants