From 29039e8bd13a4fdb7f84254038b3331c179273fd Mon Sep 17 00:00:00 2001 From: Niranjan Jayakar Date: Mon, 29 Nov 2021 17:44:35 +0000 Subject: [PATCH] chore(apigatewayv2): integration api re-organization (#17752) There are three major changes. `HttpRouteIntegration` (and its sibling `WebSocketRouteIntegration`) creates a CDK construct (`HttpIntegration` and `WebSocketIntegration`) as part of its bind operation. The id to this CDK construct is determined by hashing the results of the bind. Using hashes makes the construct id fragile/sensitive, consequently the CFN resource's logical id fragile. The fragility comes mainly from the question - have we hashed all of the expected properties that should be hashed, and nothing extra? If we have not hashed properties that should be there, or hashed too much, we end up with a hash change, hence resource replacement that is unexpected. This commit changes this approach and asks the user to provide the construct's id. This is more aligned with the current CDK expectation that users provide an id when initializing constructs. We just don't have a good way to validate that our hashing is accurate, so let's not do it at all. This change makes the user provide a unique name within a scope, which is already a standard requirement for CDK constructs. Secondly, the ergonomics of specific integration implementations, such as, `LambdaProxyIntegration`, `HttpAlbIntegration`, etc. is modified so that the integrating primitive is moved out of the 'props', and to the constructor. The API ergonomics of this feels much better than having to always provide a 'props'. Since this package contains constructs around both http api and websocket api, the convention to follow is that all classes specific to the former will be prefixed with `Http` and the latter will be prefixed with `WebSocket`. Bring the integration classes `LambdaProxyIntegration` and `HttpProxyIntegration` in line with this convention. These are renamed to `HttpLambdaIntegration` and `HttpUrlIntegration` respectively. BREAKING CHANGE: The `HttpIntegration` and `WebSocketIntegration` classes require an "id" parameter to be provided during its initialization. * **apigatewayv2-integrations:** The `LambdaWebSocketIntegration` is now renamed to `WebSocketLambdaIntegration`. The new class accepts the handler to the target lambda function directly in its constructor. * **apigatewayv2-integrations:** `HttpProxyIntegration` and `HttpProxyIntegrationProps` are now renamed to `HttpUrlIntegration` and `HttpUrlIntegrationProps` respectively. The new class accepts the target url directly in its constructor. * **apigatewayv2-integrations:** `LambdaProxyIntegration` and `LambdaProxyIntegrationProps` are now renamed to `HttpLambdaIntegration` and `HttpLambdaIntegrationProps` respectively. The new class accepts the lambda function handler directly in its constructor. * **apigatewayv2-integrations:** `HttpAlbIntegration` now accepts the ELB listener directly in its constructor. * **apigatewayv2-integrations:** `HttpNlbIntegration` now accepts the ELB listener directly in its constructor. * **apigatewayv2-integrations:** `HttpServiceDiscoveryIntegration` now accepts the service discovery Service directly in its constructor. * **apigatewayv2-authorizers:** `UserPoolAuthorizerProps` is now renamed to `HttpUserPoolAuthorizerProps`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-apigatewayv2-authorizers/README.md | 36 +++++------------ .../lib/http/user-pool.ts | 6 +-- .../test/http/integ.lambda.expected.json | 6 +-- .../test/http/integ.lambda.ts | 4 +- .../test/http/integ.user-pool.expected.json | 8 ++-- .../test/http/integ.user-pool.ts | 4 +- .../test/http/integration.ts | 15 +++++++ .../test/http/jwt.test.ts | 13 +----- .../test/http/lambda.test.ts | 13 +----- .../test/http/user-pool.test.ts | 13 +----- .../aws-apigatewayv2-integrations/README.md | 35 +++++----------- .../lib/http/alb.ts | 23 ++++++----- .../lib/http/http-proxy.ts | 20 +++++----- .../lib/http/lambda.ts | 31 ++++++++------ .../lib/http/nlb.ts | 23 ++++++----- .../lib/http/service-discovery.ts | 19 +++++---- .../lib/websocket/lambda.ts | 29 +++++++------- .../test/http/alb.test.ts | 26 +++--------- .../test/http/http-proxy.test.ts | 11 ++--- .../test/http/integ.alb.expected.json | 4 +- .../test/http/integ.alb.ts | 4 +- .../test/http/integ.http-proxy.expected.json | 10 ++--- .../test/http/integ.http-proxy.ts | 10 ++--- .../http/integ.lambda-proxy.expected.json | 6 +-- .../test/http/integ.lambda-proxy.ts | 6 +-- .../test/http/integ.nlb.expected.json | 22 +++++----- .../test/http/integ.nlb.ts | 4 +- .../integ.service-discovery.expected.json | 22 +++++----- .../test/http/integ.service-discovery.ts | 3 +- .../test/http/lambda.test.ts | 16 +++----- .../test/http/nlb.test.ts | 26 +++--------- .../test/http/private/integration.test.ts | 2 +- .../test/http/service-discovery.test.ts | 19 +++------ .../test/websocket/integ.lambda.expected.json | 24 +++++------ .../test/websocket/integ.lambda.ts | 10 ++--- .../test/websocket/lambda.test.ts | 4 +- packages/@aws-cdk/aws-apigatewayv2/README.md | 40 ++++++++----------- .../aws-apigatewayv2/lib/http/integration.ts | 18 ++++----- .../lib/websocket/integration.ts | 17 ++++---- .../aws-apigatewayv2/test/http/api.test.ts | 4 ++ .../aws-apigatewayv2/test/http/route.test.ts | 10 +++-- .../test/websocket/api.test.ts | 4 ++ .../test/websocket/route.test.ts | 6 ++- .../integ.call-http-api.expected.json | 6 +-- .../test/apigateway/integ.call-http-api.ts | 4 +- 45 files changed, 281 insertions(+), 355 deletions(-) create mode 100644 packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integration.ts diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md b/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md index 7da981240612e..df0a69a82b11e 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md @@ -71,7 +71,7 @@ The example below showcases default authorization, along with route authorizatio ```ts import { HttpJwtAuthorizer } from '@aws-cdk/aws-apigatewayv2-authorizers'; -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; const authorizer = new HttpJwtAuthorizer({ jwtAudience: ['3131231'], @@ -84,34 +84,26 @@ const api = new apigwv2.HttpApi(this, 'HttpApi', { }); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books', methods: [apigwv2.HttpMethod.GET], }); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIdIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books/{id}', methods: [apigwv2.HttpMethod.GET], }); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books', methods: [apigwv2.HttpMethod.POST], authorizationScopes: ['write:books'] }); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('LoginIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/login', methods: [apigwv2.HttpMethod.POST], authorizer: new apigwv2.HttpNoneAuthorizer(), @@ -136,7 +128,7 @@ Clients that fail authorization are presented with either 2 responses: ```ts import { HttpJwtAuthorizer } from '@aws-cdk/aws-apigatewayv2-authorizers'; -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; const authorizer = new HttpJwtAuthorizer({ jwtAudience: ['3131231'], @@ -146,9 +138,7 @@ const authorizer = new HttpJwtAuthorizer({ const api = new apigwv2.HttpApi(this, 'HttpApi'); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books', authorizer, }); @@ -165,7 +155,7 @@ pools as authorizer](https://docs.aws.amazon.com/apigateway/latest/developerguid ```ts import * as cognito from '@aws-cdk/aws-cognito'; import { HttpUserPoolAuthorizer } from '@aws-cdk/aws-apigatewayv2-authorizers'; -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; const userPool = new cognito.UserPool(this, 'UserPool'); const userPoolClient = userPool.addClient('UserPoolClient'); @@ -178,9 +168,7 @@ const authorizer = new HttpUserPoolAuthorizer({ const api = new apigwv2.HttpApi(this, 'HttpApi'); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books', authorizer, }); @@ -195,7 +183,7 @@ Lambda authorizers depending on their response, fall into either two types - Sim ```ts import { HttpLambdaAuthorizer, HttpLambdaResponseType } from '@aws-cdk/aws-apigatewayv2-authorizers'; -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; // This function handles your auth logic declare const authHandler: lambda.Function; @@ -209,9 +197,7 @@ const authorizer = new HttpLambdaAuthorizer({ const api = new apigwv2.HttpApi(this, 'HttpApi'); api.addRoutes({ - integration: new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', - }), + integration: new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'), path: '/books', authorizer, }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts index 21cef2e478756..cd4e39ad03fea 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts @@ -3,9 +3,9 @@ import { IUserPool, IUserPoolClient } from '@aws-cdk/aws-cognito'; import { Stack, Token } from '@aws-cdk/core'; /** - * Properties to initialize UserPoolAuthorizer. + * Properties to initialize HttpUserPoolAuthorizer. */ -export interface UserPoolAuthorizerProps { +export interface HttpUserPoolAuthorizerProps { /** * The user pool clients that should be used to authorize requests with the user pool. */ @@ -43,7 +43,7 @@ export interface UserPoolAuthorizerProps { export class HttpUserPoolAuthorizer implements IHttpRouteAuthorizer { private authorizer?: HttpAuthorizer; - constructor(private readonly props: UserPoolAuthorizerProps) { + constructor(private readonly props: HttpUserPoolAuthorizerProps) { } public bind(options: HttpRouteAuthorizerBindOptions): HttpRouteAuthorizerConfig { diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.expected.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.expected.json index 6f0d30c71ad66..29ee6fe741501 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.expected.json @@ -17,7 +17,7 @@ "AutoDeploy": true } }, - "MyHttpApiGETAuthorizerIntegMyHttpApiGET16D02385PermissionBB02EBFE": { + "MyHttpApiGETRootIntegrationPermission81613491": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -54,7 +54,7 @@ } } }, - "MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31": { + "MyHttpApiGETRootIntegration5068C5B0": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -87,7 +87,7 @@ [ "integrations/", { - "Ref": "MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31" + "Ref": "MyHttpApiGETRootIntegration5068C5B0" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.ts index 264da5f4bf510..9bc2326da21c9 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.lambda.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2'; -import { LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, Stack, CfnOutput } from '@aws-cdk/core'; import { HttpLambdaAuthorizer, HttpLambdaResponseType } from '../../lib'; @@ -40,7 +40,7 @@ const handler = new lambda.Function(stack, 'lambda', { httpApi.addRoutes({ path: '/', methods: [HttpMethod.GET], - integration: new LambdaProxyIntegration({ handler }), + integration: new HttpLambdaIntegration('RootIntegration', handler), authorizer, }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.expected.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.expected.json index c3ddc2fbc6e94..3e8577dfa278c 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.expected.json @@ -17,7 +17,7 @@ "AutoDeploy": true } }, - "MyHttpApiGETAuthorizerIntegMyHttpApiGET16D02385PermissionBB02EBFE": { + "MyHttpApiGETRootIntegratinPermissionCEEEB498": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -54,7 +54,7 @@ } } }, - "MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31": { + "MyHttpApiGETRootIntegratin93150A89": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -87,7 +87,7 @@ [ "integrations/", { - "Ref": "MyHttpApiGETHttpIntegration6f095b8469365f72e33fa33d9711b140516EBE31" + "Ref": "MyHttpApiGETRootIntegratin93150A89" } ] ] @@ -101,10 +101,10 @@ "Ref": "MyHttpApi8AEAAC21" }, "AuthorizerType": "JWT", + "Name": "UserPoolAuthorizer", "IdentitySource": [ "$request.header.Authorization" ], - "Name": "UserPoolAuthorizer", "JwtConfiguration": { "Audience": [ { diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts index 3e607b4474365..6e9ddd8e69b5c 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts @@ -1,7 +1,7 @@ /// !cdk-integ pragma:ignore-assets import * as path from 'path'; import { HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2'; -import { LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; import * as cognito from '@aws-cdk/aws-cognito'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, Stack } from '@aws-cdk/core'; @@ -37,6 +37,6 @@ const handler = new lambda.Function(stack, 'lambda', { httpApi.addRoutes({ path: '/', methods: [HttpMethod.GET], - integration: new LambdaProxyIntegration({ handler }), + integration: new HttpLambdaIntegration('RootIntegratin', handler), authorizer, }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integration.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integration.ts new file mode 100644 index 0000000000000..bfabca0545ea5 --- /dev/null +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integration.ts @@ -0,0 +1,15 @@ +import { HttpIntegrationType, HttpRouteIntegration, HttpRouteIntegrationBindOptions, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; + +export class DummyRouteIntegration extends HttpRouteIntegration { + constructor() { + super('DummyRouteIntegration'); + } + + public bind(_: HttpRouteIntegrationBindOptions) { + return { + payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, + type: HttpIntegrationType.HTTP_PROXY, + uri: 'some-uri', + }; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts index c65642d8df4d3..1d91a37438cfb 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts @@ -1,7 +1,8 @@ import { Template } from '@aws-cdk/assertions'; -import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, HttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; +import { HttpApi } from '@aws-cdk/aws-apigatewayv2'; import { Stack } from '@aws-cdk/core'; import { HttpJwtAuthorizer } from '../../lib'; +import { DummyRouteIntegration } from './integration'; describe('HttpJwtAuthorizer', () => { test('default', () => { @@ -58,13 +59,3 @@ describe('HttpJwtAuthorizer', () => { Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Authorizer', 1); }); }); - -class DummyRouteIntegration extends HttpRouteIntegration { - public bind(_: HttpRouteIntegrationBindOptions) { - return { - payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, - type: HttpIntegrationType.HTTP_PROXY, - uri: 'some-uri', - }; - } -} diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts index 28b007dafd359..8ced20b3c1e1e 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts @@ -1,8 +1,9 @@ import { Match, Template } from '@aws-cdk/assertions'; -import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, HttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; +import { HttpApi } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { Duration, Stack } from '@aws-cdk/core'; import { HttpLambdaAuthorizer, HttpLambdaResponseType } from '../../lib'; +import { DummyRouteIntegration } from './integration'; describe('HttpLambdaAuthorizer', () => { @@ -169,13 +170,3 @@ describe('HttpLambdaAuthorizer', () => { }); }); }); - -class DummyRouteIntegration extends HttpRouteIntegration { - public bind(_: HttpRouteIntegrationBindOptions) { - return { - payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, - type: HttpIntegrationType.HTTP_PROXY, - uri: 'some-uri', - }; - } -} diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts index 7189c060b877b..21bda048b1a4d 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts @@ -1,8 +1,9 @@ import { Template } from '@aws-cdk/assertions'; -import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, HttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; +import { HttpApi } from '@aws-cdk/aws-apigatewayv2'; import { UserPool } from '@aws-cdk/aws-cognito'; import { Stack } from '@aws-cdk/core'; import { HttpUserPoolAuthorizer } from '../../lib'; +import { DummyRouteIntegration } from './integration'; describe('HttpUserPoolAuthorizer', () => { test('default', () => { @@ -111,13 +112,3 @@ describe('HttpUserPoolAuthorizer', () => { }); }); }); - -class DummyRouteIntegration extends HttpRouteIntegration { - public bind(_: HttpRouteIntegrationBindOptions) { - return { - payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, - type: HttpIntegrationType.HTTP_PROXY, - uri: 'some-uri', - }; - } -} diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/README.md b/packages/@aws-cdk/aws-apigatewayv2-integrations/README.md index d284be9491e99..07c2d3310cc5b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/README.md +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/README.md @@ -41,12 +41,10 @@ proxy integrations](https://docs.aws.amazon.com/apigateway/latest/developerguide The following code configures a route `GET /books` with a Lambda proxy integration. ```ts -import { LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; declare const booksDefaultFn: lambda.Function; -const booksIntegration = new LambdaProxyIntegration({ - handler: booksDefaultFn, -}); +const booksIntegration = new HttpLambdaIntegration('BooksIntegration', booksDefaultFn); const httpApi = new apigwv2.HttpApi(this, 'HttpApi'); @@ -68,11 +66,9 @@ The following code configures a route `GET /books` with an HTTP proxy integratio `get-books-proxy.myproxy.internal`. ```ts -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; -const booksIntegration = new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', -}); +const booksIntegration = new HttpUrlIntegration('BooksIntegration', 'https://get-books-proxy.myproxy.internal'); const httpApi = new apigwv2.HttpApi(this, 'HttpApi'); @@ -106,9 +102,7 @@ listener.addTargets('target', { }); const httpEndpoint = new apigwv2.HttpApi(this, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpAlbIntegration({ - listener, - }), + defaultIntegration: new HttpAlbIntegration('DefaultIntegration', listener), }); ``` @@ -129,9 +123,7 @@ listener.addTargets('target', { }); const httpEndpoint = new apigwv2.HttpApi(this, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpNlbIntegration({ - listener, - }), + defaultIntegration: new HttpNlbIntegration('DefaultIntegration', listener), }); ``` @@ -154,9 +146,8 @@ const namespace = new servicediscovery.PrivateDnsNamespace(this, 'Namespace', { const service = namespace.createService('Service'); const httpEndpoint = new apigwv2.HttpApi(this, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpServiceDiscoveryIntegration({ + defaultIntegration: new HttpServiceDiscoveryIntegration('DefaultIntegration', service, { vpcLink, - service, }), }); ``` @@ -179,8 +170,7 @@ listener.addTargets('target', { }); const httpEndpoint = new apigwv2.HttpApi(this, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpAlbIntegration({ - listener, + defaultIntegration: new HttpAlbIntegration('DefaultIntegration', listener, { parameterMapping: new apigwv2.ParameterMapping() .appendHeader('header2', apigwv2.MappingValue.requestHeader('header1')) .removeHeader('header1'), @@ -200,8 +190,7 @@ listener.addTargets('target', { }); const httpEndpoint = new apigwv2.HttpApi(this, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpAlbIntegration({ - listener, + defaultIntegration: new HttpAlbIntegration('DefaultIntegration', listener, { parameterMapping: new apigwv2.ParameterMapping().custom('myKey', 'myValue'), }), }); @@ -222,7 +211,7 @@ The API Gateway service will invoke the lambda function with an event payload of The following code configures a `sendmessage` route with a Lambda integration ```ts -import { LambdaWebSocketIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { WebSocketLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; const webSocketApi = new apigwv2.WebSocketApi(this, 'mywsapi'); new apigwv2.WebSocketStage(this, 'mystage', { @@ -233,8 +222,6 @@ new apigwv2.WebSocketStage(this, 'mystage', { declare const messageHandler: lambda.Function; webSocketApi.addRoute('sendmessage', { - integration: new LambdaWebSocketIntegration({ - handler: messageHandler, - }), + integration: new WebSocketLambdaIntegration('SendMessageIntegration', messageHandler), }); ``` diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/alb.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/alb.ts index e5e6d5c448663..d7795f909f874 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/alb.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/alb.ts @@ -8,24 +8,29 @@ import { HttpPrivateIntegration } from './private/integration'; * Properties to initialize `HttpAlbIntegration`. */ export interface HttpAlbIntegrationProps extends HttpPrivateIntegrationOptions { - /** - * The listener to the application load balancer used for the integration - */ - readonly listener: elbv2.IApplicationListener; } /** * The Application Load Balancer integration resource for HTTP API */ export class HttpAlbIntegration extends HttpPrivateIntegration { - constructor(private readonly props: HttpAlbIntegrationProps) { - super(); + /** + * @param id id of the underlying integration construct + * @param listener the ELB application listener + * @param props properties to configure the integration + */ + constructor( + id: string, + private readonly listener: elbv2.IApplicationListener, + private readonly props: HttpAlbIntegrationProps = {}) { + + super(id); } public bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { let vpc: ec2.IVpc | undefined = this.props.vpcLink?.vpc; - if (!vpc && (this.props.listener instanceof elbv2.ApplicationListener)) { - vpc = this.props.listener.loadBalancer.vpc; + if (!vpc && (this.listener instanceof elbv2.ApplicationListener)) { + vpc = this.listener.loadBalancer.vpc; } if (!vpc) { throw new Error('The vpcLink property must be specified when using an imported Application Listener.'); @@ -42,7 +47,7 @@ export class HttpAlbIntegration extends HttpPrivateIntegration { type: this.integrationType, connectionType: this.connectionType, connectionId: vpcLink.vpcLinkId, - uri: this.props.listener.listenerArn, + uri: this.listener.listenerArn, secureServerName: this.props.secureServerName, parameterMapping: this.props.parameterMapping, }; diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/http-proxy.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/http-proxy.ts index 879912ee881cf..c0b3104653cc2 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/http-proxy.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/http-proxy.ts @@ -11,12 +11,7 @@ import { /** * Properties to initialize a new `HttpProxyIntegration`. */ -export interface HttpProxyIntegrationProps { - /** - * The full-qualified HTTP URL for the HTTP integration - */ - readonly url: string - +export interface HttpUrlIntegrationProps { /** * The HTTP method that must be used to invoke the underlying HTTP proxy. * @default HttpMethod.ANY @@ -34,9 +29,14 @@ export interface HttpProxyIntegrationProps { /** * The HTTP Proxy integration resource for HTTP API */ -export class HttpProxyIntegration extends HttpRouteIntegration { - constructor(private readonly props: HttpProxyIntegrationProps) { - super(); +export class HttpUrlIntegration extends HttpRouteIntegration { + /** + * @param id id of the underlying integration construct + * @param url the URL to proxy to + * @param props properties to configure the integration + */ + constructor(id: string, private readonly url: string, private readonly props: HttpUrlIntegrationProps = {}) { + super(id); } public bind(_: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { @@ -44,7 +44,7 @@ export class HttpProxyIntegration extends HttpRouteIntegration { method: this.props.method ?? HttpMethod.ANY, payloadFormatVersion: PayloadFormatVersion.VERSION_1_0, // 1.0 is required and is the only supported format type: HttpIntegrationType.HTTP_PROXY, - uri: this.props.url, + uri: this.url, parameterMapping: this.props.parameterMapping, }; } diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts index ff5750da71077..6bdce918195cf 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts @@ -8,17 +8,12 @@ import { } from '@aws-cdk/aws-apigatewayv2'; import { ServicePrincipal } from '@aws-cdk/aws-iam'; import { IFunction } from '@aws-cdk/aws-lambda'; -import { Names, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; /** * Lambda Proxy integration properties */ -export interface LambdaProxyIntegrationProps { - /** - * The handler for this integration. - */ - readonly handler: IFunction - +export interface HttpLambdaIntegrationProps { /** * Version of the payload sent to the lambda handler. * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html @@ -37,15 +32,27 @@ export interface LambdaProxyIntegrationProps { /** * The Lambda Proxy integration resource for HTTP API */ -export class LambdaProxyIntegration extends HttpRouteIntegration { +export class HttpLambdaIntegration extends HttpRouteIntegration { + + private readonly _id: string; + + /** + * @param id id of the underlying integration construct + * @param handler the Lambda handler to integrate with + * @param props properties to configure the integration + */ + constructor( + id: string, + private readonly handler: IFunction, + private readonly props: HttpLambdaIntegrationProps = {}) { - constructor(private readonly props: LambdaProxyIntegrationProps) { - super(); + super(id); + this._id = id; } public bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { const route = options.route; - this.props.handler.addPermission(`${Names.nodeUniqueId(route.node)}-Permission`, { + this.handler.addPermission(`${this._id}-Permission`, { scope: options.scope, principal: new ServicePrincipal('apigateway.amazonaws.com'), sourceArn: Stack.of(route).formatArn({ @@ -57,7 +64,7 @@ export class LambdaProxyIntegration extends HttpRouteIntegration { return { type: HttpIntegrationType.LAMBDA_PROXY, - uri: this.props.handler.functionArn, + uri: this.handler.functionArn, payloadFormatVersion: this.props.payloadFormatVersion ?? PayloadFormatVersion.VERSION_2_0, parameterMapping: this.props.parameterMapping, }; diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/nlb.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/nlb.ts index 7aae0aa002354..a7b7690ef3ed4 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/nlb.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/nlb.ts @@ -8,24 +8,29 @@ import { HttpPrivateIntegration } from './private/integration'; * Properties to initialize `HttpNlbIntegration`. */ export interface HttpNlbIntegrationProps extends HttpPrivateIntegrationOptions { - /** - * The listener to the network load balancer used for the integration - */ - readonly listener: elbv2.INetworkListener; } /** * The Network Load Balancer integration resource for HTTP API */ export class HttpNlbIntegration extends HttpPrivateIntegration { - constructor(private readonly props: HttpNlbIntegrationProps) { - super(); + /** + * @param id id of the underlying integration construct + * @param listener the ELB network listener + * @param props properties to configure the integration + */ + constructor( + id: string, + private readonly listener: elbv2.INetworkListener, + private readonly props: HttpNlbIntegrationProps = {}) { + + super(id); } public bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { let vpc: ec2.IVpc | undefined = this.props.vpcLink?.vpc; - if (!vpc && (this.props.listener instanceof elbv2.NetworkListener)) { - vpc = this.props.listener.loadBalancer.vpc; + if (!vpc && (this.listener instanceof elbv2.NetworkListener)) { + vpc = this.listener.loadBalancer.vpc; } if (!vpc) { throw new Error('The vpcLink property must be specified when using an imported Network Listener.'); @@ -42,7 +47,7 @@ export class HttpNlbIntegration extends HttpPrivateIntegration { type: this.integrationType, connectionType: this.connectionType, connectionId: vpcLink.vpcLinkId, - uri: this.props.listener.listenerArn, + uri: this.listener.listenerArn, secureServerName: this.props.secureServerName, parameterMapping: this.props.parameterMapping, }; diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/service-discovery.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/service-discovery.ts index 6f3b8eedbea0a..3a3433abdb83b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/service-discovery.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/service-discovery.ts @@ -7,18 +7,23 @@ import { HttpPrivateIntegration } from './private/integration'; * Properties to initialize `HttpServiceDiscoveryIntegration`. */ export interface HttpServiceDiscoveryIntegrationProps extends HttpPrivateIntegrationOptions { - /** - * The discovery service used for the integration - */ - readonly service: servicediscovery.IService; } /** * The Service Discovery integration resource for HTTP API */ export class HttpServiceDiscoveryIntegration extends HttpPrivateIntegration { - constructor(private readonly props: HttpServiceDiscoveryIntegrationProps) { - super(); + /** + * @param id id of the underlying integration construct + * @param service the service discovery resource to integrate with + * @param props properties to configure the integration + */ + constructor( + id: string, + private readonly service: servicediscovery.IService, + private readonly props: HttpServiceDiscoveryIntegrationProps = {}) { + + super(id); } public bind(_: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { @@ -32,7 +37,7 @@ export class HttpServiceDiscoveryIntegration extends HttpPrivateIntegration { type: this.integrationType, connectionType: this.connectionType, connectionId: this.props.vpcLink.vpcLinkId, - uri: this.props.service.serviceArn, + uri: this.service.serviceArn, secureServerName: this.props.secureServerName, parameterMapping: this.props.parameterMapping, }; diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/websocket/lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/websocket/lambda.ts index 8e41b30d65295..a5c61af497f89 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/websocket/lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/websocket/lambda.ts @@ -6,29 +6,28 @@ import { } from '@aws-cdk/aws-apigatewayv2'; import { ServicePrincipal } from '@aws-cdk/aws-iam'; import { IFunction } from '@aws-cdk/aws-lambda'; -import { Names, Stack } from '@aws-cdk/core'; +import { Stack } from '@aws-cdk/core'; /** - * Lambda WebSocket Integration props + * Lambda WebSocket Integration */ -export interface LambdaWebSocketIntegrationProps { +export class WebSocketLambdaIntegration extends WebSocketRouteIntegration { + + private readonly _id: string; + /** - * The handler for this integration. + * @param id id of the underlying integration construct + * @param handler the Lambda function handler + * @param props properties to configure the integration */ - readonly handler: IFunction -} - -/** - * Lambda WebSocket Integration - */ -export class LambdaWebSocketIntegration extends WebSocketRouteIntegration { - constructor(private props: LambdaWebSocketIntegrationProps) { - super(); + constructor(id: string, private readonly handler: IFunction) { + super(id); + this._id = id; } bind(options: WebSocketRouteIntegrationBindOptions): WebSocketRouteIntegrationConfig { const route = options.route; - this.props.handler.addPermission(`${Names.nodeUniqueId(route.node)}-Permission`, { + this.handler.addPermission(`${this._id}-Permission`, { scope: options.scope, principal: new ServicePrincipal('apigateway.amazonaws.com'), sourceArn: Stack.of(route).formatArn({ @@ -42,7 +41,7 @@ export class LambdaWebSocketIntegration extends WebSocketRouteIntegration { service: 'apigateway', account: 'lambda', resource: 'path/2015-03-31/functions', - resourceName: `${this.props.handler.functionArn}/invocations`, + resourceName: `${this.handler.functionArn}/invocations`, }); return { diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts index 3c25e92fe6d21..c73d9c41055da 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts @@ -18,9 +18,7 @@ describe('HttpAlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - listener, - }), + integration: new HttpAlbIntegration('Integration', listener), routeKey: HttpRouteKey.with('/pets'), }); @@ -52,10 +50,7 @@ describe('HttpAlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - vpcLink, - listener, - }), + integration: new HttpAlbIntegration('Integration', listener, { vpcLink }), routeKey: HttpRouteKey.with('/pets'), }); @@ -86,10 +81,7 @@ describe('HttpAlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - listener, - method: HttpMethod.PATCH, - }), + integration: new HttpAlbIntegration('Integration', listener, { method: HttpMethod.PATCH }), routeKey: HttpRouteKey.with('/pets'), }); @@ -110,9 +102,7 @@ describe('HttpAlbIntegration', () => { expect(() => new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - listener, - }), + integration: new HttpAlbIntegration('Integration', listener), routeKey: HttpRouteKey.with('/pets'), })).toThrow(/vpcLink property must be specified/); }); @@ -129,10 +119,7 @@ describe('HttpAlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - listener, - secureServerName: 'name-to-verify', - }), + integration: new HttpAlbIntegration('Integration', listener, { secureServerName: 'name-to-verify' }), routeKey: HttpRouteKey.with('/pets'), }); @@ -156,8 +143,7 @@ describe('HttpAlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpAlbIntegration({ - listener, + integration: new HttpAlbIntegration('Integration', listener, { parameterMapping: new ParameterMapping() .appendHeader('header2', MappingValue.requestHeader('header1')) .removeHeader('header1'), diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts index 0f29ec0915fd9..3792f25d84ae1 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts @@ -1,7 +1,7 @@ import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpIntegration, HttpIntegrationType, HttpMethod, HttpRoute, HttpRouteKey, MappingValue, ParameterMapping, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Stack } from '@aws-cdk/core'; -import { HttpProxyIntegration } from '../../lib'; +import { HttpUrlIntegration } from '../../lib'; describe('HttpProxyIntegration', () => { test('default', () => { @@ -9,9 +9,7 @@ describe('HttpProxyIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyRoute', { httpApi: api, - integration: new HttpProxyIntegration({ - url: 'some-target-url', - }), + integration: new HttpUrlIntegration('Integration', 'some-target-url'), routeKey: HttpRouteKey.with('/pets'), }); @@ -28,10 +26,7 @@ describe('HttpProxyIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyRoute', { httpApi: api, - integration: new HttpProxyIntegration({ - url: 'some-target-url', - method: HttpMethod.PATCH, - }), + integration: new HttpUrlIntegration('Integration', 'some-target-url', { method: HttpMethod.PATCH }), routeKey: HttpRouteKey.with('/pets'), }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json index 65149587fb3ce..273e66ff03ac0 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json @@ -614,7 +614,7 @@ "ProtocolType": "HTTP" } }, - "HttpProxyPrivateApiDefaultRouteHttpIntegration1a580b19954e4317026ffbce1f7d5ade7A32685B": { + "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -646,7 +646,7 @@ [ "integrations/", { - "Ref": "HttpProxyPrivateApiDefaultRouteHttpIntegration1a580b19954e4317026ffbce1f7d5ade7A32685B" + "Ref": "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.ts index e077560466851..9ef01807d11d4 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.ts @@ -21,9 +21,7 @@ listener.addTargets('target', { port: 80 }); listener.addAction('dsf', { action: elbv2.ListenerAction.fixedResponse(200) }); const httpEndpoint = new HttpApi(stack, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpAlbIntegration({ - listener, - }), + defaultIntegration: new HttpAlbIntegration('DefaultIntegration', listener), }); new CfnOutput(stack, 'Endpoint', { diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json index 0e53d0a223e42..edb4305fe239b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json @@ -57,7 +57,7 @@ "ProtocolType": "HTTP" } }, - "LambdaProxyApiDefaultRouteinteghttpproxyLambdaProxyApiDefaultRoute17D52FE1Permission4875FF59": { + "LambdaProxyApiDefaultRouteDefaultIntegrationPermission39F587FC": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -94,7 +94,7 @@ } } }, - "LambdaProxyApiDefaultRouteHttpIntegration70df0ec52c3e3b6bbc96e64ce3a05f24EE575CBA": { + "LambdaProxyApiDefaultRouteDefaultIntegrationAE9908C8": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -124,7 +124,7 @@ [ "integrations/", { - "Ref": "LambdaProxyApiDefaultRouteHttpIntegration70df0ec52c3e3b6bbc96e64ce3a05f24EE575CBA" + "Ref": "LambdaProxyApiDefaultRouteDefaultIntegrationAE9908C8" } ] ] @@ -148,7 +148,7 @@ "ProtocolType": "HTTP" } }, - "HttpProxyApiDefaultRouteHttpIntegration8eeecf9ecdb91f31bebf6bd54fb711a41921AB82": { + "HttpProxyApiDefaultRouteDefaultIntegration95D23B0D": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -193,7 +193,7 @@ [ "integrations/", { - "Ref": "HttpProxyApiDefaultRouteHttpIntegration8eeecf9ecdb91f31bebf6bd54fb711a41921AB82" + "Ref": "HttpProxyApiDefaultRouteDefaultIntegration95D23B0D" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.ts index 9fa5803973376..14d0a291e7113 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.ts @@ -1,7 +1,7 @@ import { HttpApi } from '@aws-cdk/aws-apigatewayv2'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, CfnOutput, Stack } from '@aws-cdk/core'; -import { HttpProxyIntegration, LambdaProxyIntegration } from '../../lib'; +import { HttpUrlIntegration, HttpLambdaIntegration } from '../../lib'; /* * Stack verification steps: @@ -16,9 +16,7 @@ const stack = new Stack(app, 'integ-http-proxy'); const lambdaEndpoint = lambdaProxyEndpoint(stack); const httpEndpoint = new HttpApi(stack, 'HttpProxyApi', { - defaultIntegration: new HttpProxyIntegration({ - url: lambdaEndpoint.url!, - }), + defaultIntegration: new HttpUrlIntegration('DefaultIntegration', lambdaEndpoint.url!), }); new CfnOutput(stack, 'Endpoint', { @@ -33,8 +31,6 @@ function lambdaProxyEndpoint(s: Stack): HttpApi { }); return new HttpApi(s, 'LambdaProxyApi', { - defaultIntegration: new LambdaProxyIntegration({ - handler, - }), + defaultIntegration: new HttpLambdaIntegration('DefaultIntegration', handler), }); } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json index 7963d3534e099..5de2892451602 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json @@ -57,7 +57,7 @@ "ProtocolType": "HTTP" } }, - "LambdaProxyApiDefaultRouteinteglambdaproxyLambdaProxyApiDefaultRoute59CA2390Permission07F93503": { + "LambdaProxyApiDefaultRouteDefaultIntegrationPermission39F587FC": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -94,7 +94,7 @@ } } }, - "LambdaProxyApiDefaultRouteHttpIntegration70df0ec52c3e3b6bbc96e64ce3a05f24EE575CBA": { + "LambdaProxyApiDefaultRouteDefaultIntegrationAE9908C8": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -124,7 +124,7 @@ [ "integrations/", { - "Ref": "LambdaProxyApiDefaultRouteHttpIntegration70df0ec52c3e3b6bbc96e64ce3a05f24EE575CBA" + "Ref": "LambdaProxyApiDefaultRouteDefaultIntegrationAE9908C8" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.ts index ed1cabee002e4..5f8457a7d8218 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.ts @@ -1,7 +1,7 @@ import { HttpApi } from '@aws-cdk/aws-apigatewayv2'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, CfnOutput, Stack } from '@aws-cdk/core'; -import { LambdaProxyIntegration } from '../../lib'; +import { HttpLambdaIntegration } from '../../lib'; /* * Stack verification steps: @@ -19,9 +19,7 @@ const handler = new lambda.Function(stack, 'AlwaysSuccess', { }); const endpoint = new HttpApi(stack, 'LambdaProxyApi', { - defaultIntegration: new LambdaProxyIntegration({ - handler, - }), + defaultIntegration: new HttpLambdaIntegration('DefaultIntegration', handler), }); new CfnOutput(stack, 'Endpoint', { diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json index 0a3241cdc8139..ad0376a19c058 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json @@ -95,15 +95,15 @@ "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet1EIP6AD938E8", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet1SubnetB4246D30" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VPCPublicSubnet2NATGateway3C070193": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet2EIP4947BC00", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet2Subnet74179F39" - }, "Tags": [ { "Key": "Name", @@ -289,15 +289,15 @@ "VPCPublicSubnet3NATGatewayD3048F5C": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet3Subnet631C5E25" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet3EIPAD4BC883", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet3Subnet631C5E25" - }, "Tags": [ { "Key": "Name", @@ -573,7 +573,7 @@ "ProtocolType": "HTTP" } }, - "HttpProxyPrivateApiDefaultRouteHttpIntegration1a580b19954e4317026ffbce1f7d5ade7A32685B": { + "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -605,7 +605,7 @@ [ "integrations/", { - "Ref": "HttpProxyPrivateApiDefaultRouteHttpIntegration1a580b19954e4317026ffbce1f7d5ade7A32685B" + "Ref": "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.ts index 9b78c3f676e30..6c0a8e64e1f94 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.ts @@ -14,9 +14,7 @@ const listener = lb.addListener('listener', { port: 80 }); listener.addTargets('target', { port: 80 }); const httpEndpoint = new HttpApi(stack, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpNlbIntegration({ - listener, - }), + defaultIntegration: new HttpNlbIntegration('DefaultIntegration', listener), }); new CfnOutput(stack, 'Endpoint', { diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json index 00e587f8ac85f..56af47d74c0c0 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json @@ -95,15 +95,15 @@ "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet1EIP6AD938E8", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet1SubnetB4246D30" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VPCPublicSubnet2NATGateway3C070193": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet2EIP4947BC00", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet2Subnet74179F39" - }, "Tags": [ { "Key": "Name", @@ -289,15 +289,15 @@ "VPCPublicSubnet3NATGatewayD3048F5C": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet3Subnet631C5E25" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet3EIPAD4BC883", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet3Subnet631C5E25" - }, "Tags": [ { "Key": "Name", @@ -574,7 +574,7 @@ "ProtocolType": "HTTP" } }, - "HttpProxyPrivateApiDefaultRouteHttpIntegrationa5ec5390ca688d567e9449daf58afc6f6DEAA8A8": { + "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -609,7 +609,7 @@ [ "integrations/", { - "Ref": "HttpProxyPrivateApiDefaultRouteHttpIntegrationa5ec5390ca688d567e9449daf58afc6f6DEAA8A8" + "Ref": "HttpProxyPrivateApiDefaultRouteDefaultIntegration002C2760" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.ts index 1ff64ba5955c9..a79acef0d0007 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.ts @@ -17,9 +17,8 @@ const namespace = new servicediscovery.PrivateDnsNamespace(stack, 'Namespace', { const service = namespace.createService('Service'); const httpEndpoint = new HttpApi(stack, 'HttpProxyPrivateApi', { - defaultIntegration: new HttpServiceDiscoveryIntegration({ + defaultIntegration: new HttpServiceDiscoveryIntegration('DefaultIntegration', service, { vpcLink, - service, }), }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts index 85bb624a25d54..5c318e1629842 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts @@ -2,7 +2,7 @@ import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpRoute, HttpRouteKey, MappingValue, ParameterMapping, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { App, Stack } from '@aws-cdk/core'; -import { LambdaProxyIntegration } from '../../lib'; +import { HttpLambdaIntegration } from '../../lib'; describe('LambdaProxyIntegration', () => { test('default', () => { @@ -11,9 +11,7 @@ describe('LambdaProxyIntegration', () => { const fooFn = fooFunction(stack, 'Fn'); new HttpRoute(stack, 'LambdaProxyRoute', { httpApi: api, - integration: new LambdaProxyIntegration({ - handler: fooFn, - }), + integration: new HttpLambdaIntegration('Integration', fooFn), routeKey: HttpRouteKey.with('/pets'), }); @@ -29,8 +27,7 @@ describe('LambdaProxyIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'LambdaProxyRoute', { httpApi: api, - integration: new LambdaProxyIntegration({ - handler: fooFunction(stack, 'Fn'), + integration: new HttpLambdaIntegration('Integration', fooFunction(stack, 'Fn'), { payloadFormatVersion: PayloadFormatVersion.VERSION_1_0, }), routeKey: HttpRouteKey.with('/pets'), @@ -46,8 +43,7 @@ describe('LambdaProxyIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'LambdaProxyRoute', { httpApi: api, - integration: new LambdaProxyIntegration({ - handler: fooFunction(stack, 'Fn'), + integration: new HttpLambdaIntegration('Integration', fooFunction(stack, 'Fn'), { parameterMapping: new ParameterMapping() .appendHeader('header2', MappingValue.requestHeader('header1')) .removeHeader('header1'), @@ -70,9 +66,7 @@ describe('LambdaProxyIntegration', () => { const apigwStack = new Stack(app, 'apigwStack'); new HttpApi(apigwStack, 'httpApi', { - defaultIntegration: new LambdaProxyIntegration({ - handler: fooFn, - }), + defaultIntegration: new HttpLambdaIntegration('Integration', fooFn), }); expect(() => app.synth()).not.toThrow(); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts index e1e18c43f49aa..a5c6eded4b884 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts @@ -18,9 +18,7 @@ describe('HttpNlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - listener, - }), + integration: new HttpNlbIntegration('Integration', listener), routeKey: HttpRouteKey.with('/pets'), }); @@ -52,10 +50,7 @@ describe('HttpNlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - vpcLink, - listener, - }), + integration: new HttpNlbIntegration('Integration', listener, { vpcLink }), routeKey: HttpRouteKey.with('/pets'), }); @@ -86,10 +81,7 @@ describe('HttpNlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - listener, - method: HttpMethod.PATCH, - }), + integration: new HttpNlbIntegration('Integration', listener, { method: HttpMethod.PATCH }), routeKey: HttpRouteKey.with('/pets'), }); @@ -107,9 +99,7 @@ describe('HttpNlbIntegration', () => { expect(() => new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - listener, - }), + integration: new HttpNlbIntegration('Integration', listener), routeKey: HttpRouteKey.with('/pets'), })).toThrow(/vpcLink property must be specified/); }); @@ -126,10 +116,7 @@ describe('HttpNlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - listener, - secureServerName: 'name-to-verify', - }), + integration: new HttpNlbIntegration('Integration', listener, { secureServerName: 'name-to-verify' }), routeKey: HttpRouteKey.with('/pets'), }); @@ -153,8 +140,7 @@ describe('HttpNlbIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpNlbIntegration({ - listener, + integration: new HttpNlbIntegration('Integration', listener, { parameterMapping: new ParameterMapping() .appendHeader('header2', MappingValue.requestHeader('header1')) .removeHeader('header1'), diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts index 8cda89e3d2390..a7649b1fb8620 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts @@ -8,7 +8,7 @@ describe('HttpPrivateIntegration', () => { const stack = new Stack(); class DummyPrivateIntegration extends HttpPrivateIntegration { constructor() { - super(); + super('DummyPrivateIntegration'); } public bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts index e037004cada0e..1d3ece56f2cd8 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts @@ -21,10 +21,7 @@ describe('HttpServiceDiscoveryIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpServiceDiscoveryIntegration({ - vpcLink, - service, - }), + integration: new HttpServiceDiscoveryIntegration('Integration', service, { vpcLink }), routeKey: HttpRouteKey.with('/pets'), }); @@ -61,9 +58,8 @@ describe('HttpServiceDiscoveryIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpServiceDiscoveryIntegration({ + integration: new HttpServiceDiscoveryIntegration('Integration', service, { vpcLink, - service, method: HttpMethod.PATCH, }), routeKey: HttpRouteKey.with('/pets'), @@ -87,10 +83,7 @@ describe('HttpServiceDiscoveryIntegration', () => { expect(() => new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpServiceDiscoveryIntegration({ - service, - method: HttpMethod.PATCH, - }), + integration: new HttpServiceDiscoveryIntegration('Integration', service, { method: HttpMethod.PATCH }), routeKey: HttpRouteKey.with('/pets'), })).toThrow(/vpcLink property is mandatory/); }); @@ -110,9 +103,8 @@ describe('HttpServiceDiscoveryIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpServiceDiscoveryIntegration({ + integration: new HttpServiceDiscoveryIntegration('Integration', service, { vpcLink, - service, secureServerName: 'name-to-verify', }), routeKey: HttpRouteKey.with('/pets'), @@ -141,9 +133,8 @@ describe('HttpServiceDiscoveryIntegration', () => { const api = new HttpApi(stack, 'HttpApi'); new HttpRoute(stack, 'HttpProxyPrivateRoute', { httpApi: api, - integration: new HttpServiceDiscoveryIntegration({ + integration: new HttpServiceDiscoveryIntegration('Integration', service, { vpcLink, - service, parameterMapping: new ParameterMapping() .appendHeader('header2', MappingValue.requestHeader('header1')) .removeHeader('header1'), diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.expected.json index 54a0f51203342..6b344f8f1688f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.expected.json @@ -208,7 +208,7 @@ "RouteSelectionExpression": "$request.body.action" } }, - "mywsapiconnectRouteWebSocketApiIntegmywsapiconnectRoute456CB290Permission2D0BC294": { + "mywsapiconnectRouteConnectIntegrationPermission719B6E63": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -245,7 +245,7 @@ } } }, - "mywsapiconnectRouteWebSocketIntegration3025fc0297cc8d73dae555b46106edcd38569D62": { + "mywsapiconnectRouteConnectIntegrationE101DB9B": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -290,14 +290,14 @@ [ "integrations/", { - "Ref": "mywsapiconnectRouteWebSocketIntegration3025fc0297cc8d73dae555b46106edcd38569D62" + "Ref": "mywsapiconnectRouteConnectIntegrationE101DB9B" } ] ] } } }, - "mywsapidisconnectRouteWebSocketApiIntegmywsapidisconnectRoute26B84CF3PermissionB3F6D0A8": { + "mywsapidisconnectRouteDisconnectIntegrationPermissionA8197C41": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -334,7 +334,7 @@ } } }, - "mywsapidisconnectRouteWebSocketIntegrationfc84ffd6c52488b90783abae35d28ebdAE5C6063": { + "mywsapidisconnectRouteDisconnectIntegrationF927D904": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -379,14 +379,14 @@ [ "integrations/", { - "Ref": "mywsapidisconnectRouteWebSocketIntegrationfc84ffd6c52488b90783abae35d28ebdAE5C6063" + "Ref": "mywsapidisconnectRouteDisconnectIntegrationF927D904" } ] ] } } }, - "mywsapidefaultRouteWebSocketApiIntegmywsapidefaultRouteA13D926BPermission58B64FCE": { + "mywsapidefaultRouteDefaultIntegrationPermission3B7F9CA1": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -423,7 +423,7 @@ } } }, - "mywsapidefaultRouteWebSocketIntegrationa07b7cec9837e31a8c70446e1e1f1fd5055B3083": { + "mywsapidefaultRouteDefaultIntegrationFFCB3BA9": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -468,14 +468,14 @@ [ "integrations/", { - "Ref": "mywsapidefaultRouteWebSocketIntegrationa07b7cec9837e31a8c70446e1e1f1fd5055B3083" + "Ref": "mywsapidefaultRouteDefaultIntegrationFFCB3BA9" } ] ] } } }, - "mywsapisendmessageRouteWebSocketApiIntegmywsapisendmessageRoute8A775F3CPermission660FB575": { + "mywsapisendmessageRouteSendMessageIntegrationPermission92C9841E": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -512,7 +512,7 @@ } } }, - "mywsapisendmessageRouteWebSocketIntegrationeb46e3593c10ed57eb0ca9ef3247823d74153661": { + "mywsapisendmessageRouteSendMessageIntegrationD29E12F9": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -557,7 +557,7 @@ [ "integrations/", { - "Ref": "mywsapisendmessageRouteWebSocketIntegrationeb46e3593c10ed57eb0ca9ef3247823d74153661" + "Ref": "mywsapisendmessageRouteSendMessageIntegrationD29E12F9" } ] ] diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts index 01e25f906b0f8..963cc4dad0f67 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/integ.lambda.ts @@ -1,7 +1,7 @@ import { WebSocketApi, WebSocketStage } from '@aws-cdk/aws-apigatewayv2'; import * as lambda from '@aws-cdk/aws-lambda'; import { App, CfnOutput, Stack } from '@aws-cdk/core'; -import { LambdaWebSocketIntegration } from '../../lib'; +import { WebSocketLambdaIntegration } from '../../lib'; /* * Stack verification steps: @@ -39,9 +39,9 @@ const messageHandler = new lambda.Function(stack, 'MessageHandler', { }); const webSocketApi = new WebSocketApi(stack, 'mywsapi', { - connectRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: connectHandler }) }, - disconnectRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: disconnetHandler }) }, - defaultRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: defaultHandler }) }, + connectRouteOptions: { integration: new WebSocketLambdaIntegration('ConnectIntegration', connectHandler) }, + disconnectRouteOptions: { integration: new WebSocketLambdaIntegration('DisconnectIntegration', disconnetHandler) }, + defaultRouteOptions: { integration: new WebSocketLambdaIntegration('DefaultIntegration', defaultHandler) }, }); const stage = new WebSocketStage(stack, 'mystage', { webSocketApi, @@ -49,6 +49,6 @@ const stage = new WebSocketStage(stack, 'mystage', { autoDeploy: true, }); -webSocketApi.addRoute('sendmessage', { integration: new LambdaWebSocketIntegration({ handler: messageHandler }) }); +webSocketApi.addRoute('sendmessage', { integration: new WebSocketLambdaIntegration('SendMessageIntegration', messageHandler) }); new CfnOutput(stack, 'ApiEndpoint', { value: stage.url }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts index e12b09f75ed50..d5c6a99097ec8 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts @@ -2,7 +2,7 @@ import { Template } from '@aws-cdk/assertions'; import { WebSocketApi } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { Stack } from '@aws-cdk/core'; -import { LambdaWebSocketIntegration } from '../../lib'; +import { WebSocketLambdaIntegration } from '../../lib'; describe('LambdaWebSocketIntegration', () => { @@ -14,7 +14,7 @@ describe('LambdaWebSocketIntegration', () => { // WHEN new WebSocketApi(stack, 'Api', { connectRouteOptions: { - integration: new LambdaWebSocketIntegration({ handler: fooFn }), + integration: new WebSocketLambdaIntegration('Integration', fooFn), }, }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/README.md b/packages/@aws-cdk/aws-apigatewayv2/README.md index 89dcb79f6409d..6c0697287c08d 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/README.md +++ b/packages/@aws-cdk/aws-apigatewayv2/README.md @@ -76,16 +76,12 @@ As an early example, the following code snippet configures a route `GET /books` configures all other HTTP method calls to `/books` to a lambda proxy. ```ts -import { HttpProxyIntegration, LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration, HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; -const getBooksIntegration = new HttpProxyIntegration({ - url: 'https://get-books-proxy.myproxy.internal', -}); +const getBooksIntegration = new HttpUrlIntegration('GetBooksIntegration' 'https://get-books-proxy.myproxy.internal'); declare const booksDefaultFn: lambda.Function; -const booksDefaultIntegration = new LambdaProxyIntegration({ - handler: booksDefaultFn, -}); +const booksDefaultIntegration = new HttpLambdaIntegration('BooksIntegration', booksDefaultFn); const httpApi = new apigwv2.HttpApi(this, 'HttpApi'); @@ -113,12 +109,10 @@ The `defaultIntegration` option while defining HTTP APIs lets you create a defau matched when a client reaches a route that is not explicitly defined. ```ts -import { HttpProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpUrlIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; new apigwv2.HttpApi(this, 'HttpProxyApi', { - defaultIntegration: new HttpProxyIntegration({ - url:'http://example.com', - }), + defaultIntegration: new HttpUrlIntegration('DefaultIntegration', 'https://example.com'), }); ``` @@ -183,7 +177,7 @@ custom domain to the `$default` stage of the API. ```ts import * as acm from '@aws-cdk/aws-certificatemanager'; -import { LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; const certArn = 'arn:aws:acm:us-east-1:111111111111:certificate'; const domainName = 'example.com'; @@ -195,7 +189,7 @@ const dn = new apigwv2.DomainName(this, 'DN', { declare const handler: lambda.Function; const api = new apigwv2.HttpApi(this, 'HttpProxyProdApi', { - defaultIntegration: new LambdaProxyIntegration({ handler }), + defaultIntegration: new HttpLambdaIntegration('DefaultIntegration', handler), // https://${dn.domainName}/foo goes to prodApi $default stage defaultDomainMapping: { domainName: dn, @@ -228,13 +222,13 @@ api.addStage('beta', { The same domain name can be associated with stages across different `HttpApi` as so - ```ts -import { LambdaProxyIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; declare const handler: lambda.Function; declare const dn: apigwv2.DomainName; const apiDemo = new apigwv2.HttpApi(this, 'DemoApi', { - defaultIntegration: new LambdaProxyIntegration({ handler }), + defaultIntegration: new HttpLambdaIntegration('DefaultIntegration', handler), // https://${dn.domainName}/demo goes to apiDemo $default stage defaultDomainMapping: { domainName: dn, @@ -344,7 +338,7 @@ Private integrations enable integrating an HTTP API route with private resources Amazon ECS container-based applications. Using private integrations, resources in a VPC can be exposed for access by clients outside of the VPC. -These integrations can be found in the [APIGatewayV2-Integrations](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-apigatewayv2-integrations-readme.html) constructs library. +These integrations can be found in the [aws-apigatewayv2-integrations](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-apigatewayv2-integrations-readme.html) constructs library. ## WebSocket API @@ -365,16 +359,16 @@ Integrations are available in the `aws-apigatewayv2-integrations` module and mor To add the default WebSocket routes supported by API Gateway (`$connect`, `$disconnect` and `$default`), configure them as part of api props: ```ts -import { LambdaWebSocketIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { WebSocketLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; declare const connectHandler: lambda.Function; declare const disconnectHandler: lambda.Function; declare const defaultHandler: lambda.Function; const webSocketApi = new apigwv2.WebSocketApi(this, 'mywsapi', { - connectRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: connectHandler }) }, - disconnectRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: disconnectHandler }) }, - defaultRouteOptions: { integration: new LambdaWebSocketIntegration({ handler: defaultHandler }) }, + connectRouteOptions: { integration: new WebSocketLambdaIntegration('ConnectIntegration', connectHandler) }, + disconnectRouteOptions: { integration: new WebSocketLambdaIntegration('DisconnectIntegration',disconnectHandler) }, + defaultRouteOptions: { integration: new WebSocketLambdaIntegration('DefaultIntegration', defaultHandler) }, }); new apigwv2.WebSocketStage(this, 'mystage', { @@ -398,14 +392,12 @@ const callbackURL = webSocketStage.callbackUrl; To add any other route: ```ts -import { LambdaWebSocketIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; +import { WebSocketLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; declare const messageHandler: lambda.Function; const webSocketApi = new apigwv2.WebSocketApi(this, 'mywsapi'); webSocketApi.addRoute('sendmessage', { - integration: new LambdaWebSocketIntegration({ - handler: messageHandler, - }), + integration: new WebSocketLambdaIntegration('SendMessageIntegration', messageHandler), }); ``` diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts index 6865875af5c80..857ef57657736 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts @@ -1,6 +1,4 @@ -/* eslint-disable quotes */ -import * as crypto from 'crypto'; -import { Resource, Stack } from '@aws-cdk/core'; +import { Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnIntegration } from '../apigatewayv2.generated'; import { IIntegration } from '../common'; @@ -195,6 +193,12 @@ export interface HttpRouteIntegrationBindOptions { export abstract class HttpRouteIntegration { private integration?: HttpIntegration; + /** + * Initialize an integration for a route on http api. + * @param id id of the underlying `HttpIntegration` construct. + */ + constructor(private readonly id: string) {} + /** * Internal method called when binding this integration to the route. * @internal @@ -207,7 +211,7 @@ export abstract class HttpRouteIntegration { if (!this.integration) { const config = this.bind(options); - this.integration = new HttpIntegration(options.scope, `HttpIntegration-${hash(config)}`, { + this.integration = new HttpIntegration(options.scope, this.id, { httpApi: options.route.httpApi, integrationType: config.type, integrationUri: config.uri, @@ -218,12 +222,6 @@ export abstract class HttpRouteIntegration { secureServerName: config.secureServerName, parameterMapping: config.parameterMapping, }); - - function hash(x: any) { - const stringifiedConfig = JSON.stringify(Stack.of(options.scope).resolve(x)); - const configHash = crypto.createHash('md5').update(stringifiedConfig).digest('hex'); - return configHash; - } } return { integrationId: this.integration.integrationId }; } diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/websocket/integration.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/websocket/integration.ts index 3c59269b474f6..b5366be83f2ba 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/websocket/integration.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/websocket/integration.ts @@ -1,5 +1,4 @@ -import * as crypto from 'crypto'; -import { Resource, Stack } from '@aws-cdk/core'; +import { Resource } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnIntegration } from '../apigatewayv2.generated'; import { IIntegration } from '../common'; @@ -91,6 +90,12 @@ export interface WebSocketRouteIntegrationBindOptions { export abstract class WebSocketRouteIntegration { private integration?: WebSocketIntegration; + /** + * Initialize an integration for a route on websocket api. + * @param id id of the underlying `WebSocketIntegration` construct. + */ + constructor(private readonly id: string) {} + /** * Internal method called when binding this integration to the route. * @internal @@ -103,17 +108,11 @@ export abstract class WebSocketRouteIntegration { if (!this.integration) { const config = this.bind(options); - this.integration = new WebSocketIntegration(options.scope, `WebSocketIntegration-${hash(config)}`, { + this.integration = new WebSocketIntegration(options.scope, this.id, { webSocketApi: options.route.webSocketApi, integrationType: config.type, integrationUri: config.uri, }); - - function hash(x: any) { - const stringifiedConfig = JSON.stringify(Stack.of(options.scope).resolve(x)); - const configHash = crypto.createHash('md5').update(stringifiedConfig).digest('hex'); - return configHash; - } } return { integrationId: this.integration.integrationId }; diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts index 658b139193612..bb123c6815adc 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts @@ -532,6 +532,10 @@ describe('HttpApi', () => { }); class DummyRouteIntegration extends HttpRouteIntegration { + constructor() { + super('DummyRouteIntegration'); + } + public bind(_: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { return { payloadFormatVersion: PayloadFormatVersion.VERSION_2_0, diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts index b5ddae7919a62..df917fffe0ac8 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts @@ -28,7 +28,7 @@ describe('HttpRoute', () => { [ 'integrations/', { - Ref: 'HttpRouteHttpIntegrationcff2618c192d3bd8581dd2a4093464f6FB1097D0', + Ref: 'HttpRouteDummyIntegration10F77519', }, ], ], @@ -187,7 +187,7 @@ describe('HttpRoute', () => { // WHEN new HttpRoute(stack, 'HttpRoute', { httpApi, - integration: new PrivateIntegration(), + integration: new PrivateIntegration('PrivateIntegration'), routeKey: HttpRouteKey.with('/books', HttpMethod.GET), }); @@ -229,7 +229,7 @@ describe('HttpRoute', () => { // WHEN new HttpRoute(stack, 'HttpRoute', { httpApi, - integration: new PrivateIntegration(), + integration: new PrivateIntegration('PrivateIntegration'), routeKey: HttpRouteKey.with('/books', HttpMethod.GET), }); @@ -311,6 +311,10 @@ describe('HttpRoute', () => { }); class DummyIntegration extends HttpRouteIntegration { + constructor(name?: string) { + super(name ?? 'DummyIntegration'); + } + public bind(): HttpRouteIntegrationConfig { return { type: HttpIntegrationType.HTTP_PROXY, diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts index 0a5e7c05b706d..50e973d445731 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts @@ -127,6 +127,10 @@ describe('WebSocketApi', () => { }); class DummyIntegration extends WebSocketRouteIntegration { + constructor() { + super('DummyIntegration'); + } + bind(_options: WebSocketRouteIntegrationBindOptions): WebSocketRouteIntegrationConfig { return { type: WebSocketIntegrationType.AWS_PROXY, diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts index 512006fb8a2a4..655390f31165f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts @@ -28,7 +28,7 @@ describe('WebSocketRoute', () => { [ 'integrations/', { - Ref: 'RouteWebSocketIntegrationb7742333c7ab20d7b2b178df59bb17f20338431E', + Ref: 'RouteDummyIntegrationE40E82B4', }, ], ], @@ -85,6 +85,10 @@ describe('WebSocketRoute', () => { class DummyIntegration extends WebSocketRouteIntegration { + constructor(name?: string) { + super(name ?? 'DummyIntegration'); + } + bind(_options: WebSocketRouteIntegrationBindOptions): WebSocketRouteIntegrationConfig { return { type: WebSocketIntegrationType.AWS_PROXY, diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json index c6a6abaa89273..6f0435b70af0b 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json @@ -17,7 +17,7 @@ "AutoDeploy": true } }, - "MyHttpApiANYCallHttpApiIntegMyHttpApiANY7E6F12A3Permission59116CA6": { + "MyHttpApiANYDefaultIntegrationPermissionAB8301EF": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", @@ -54,7 +54,7 @@ } } }, - "MyHttpApiANYHttpIntegration71abbf75d6f8e5ea93ec2120c0d78b754BBCECF5": { + "MyHttpApiANYDefaultIntegration5FAD8850": { "Type": "AWS::ApiGatewayV2::Integration", "Properties": { "ApiId": { @@ -84,7 +84,7 @@ [ "integrations/", { - "Ref": "MyHttpApiANYHttpIntegration71abbf75d6f8e5ea93ec2120c0d78b754BBCECF5" + "Ref": "MyHttpApiANYDefaultIntegration5FAD8850" } ] ] diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.ts index 214f2e5a25ba9..aad59d754950d 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.ts @@ -24,9 +24,7 @@ const handler = new lambda.Function(stack, 'HelloHandler', { }); httpApi.addRoutes({ path: '/', - integration: new integrations.LambdaProxyIntegration({ - handler, - }), + integration: new integrations.HttpLambdaIntegration('DefaultIntegration', handler), }); const callEndpointJob = new CallApiGatewayHttpApiEndpoint(stack, 'Call APIGW', {