From d0021fdd79e86e61a2238f8278f673e1bd33e88d Mon Sep 17 00:00:00 2001 From: Sludge Date: Fri, 16 Jun 2023 10:29:29 +0100 Subject: [PATCH 1/4] Add in method option to allow methods other than POST to webhooks --- src/constructs/aws/Webhook.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/constructs/aws/Webhook.ts b/src/constructs/aws/Webhook.ts index 3e0c2f20..cfb1fd78 100644 --- a/src/constructs/aws/Webhook.ts +++ b/src/constructs/aws/Webhook.ts @@ -28,12 +28,14 @@ const WEBHOOK_DEFINITION = { insecure: { type: "boolean" }, path: { type: "string" }, eventType: { type: "string" }, + method: { type: "string" }, }, required: ["path"], additionalProperties: false, } as const; const WEBHOOK_DEFAULTS = { insecure: false, + method: "POST", }; type Configuration = FromSchema; @@ -46,6 +48,7 @@ export class Webhook extends AwsConstruct { private readonly bus: EventBus; private readonly apiEndpointOutput: CfnOutput; private readonly endpointPathOutput: CfnOutput; + private readonly method: string; constructor( scope: CdkConstruct, @@ -108,9 +111,10 @@ export class Webhook extends AwsConstruct { EventBusName: this.bus.eventBusName, }, }); + this.method = resolvedConfiguration.method; const route = new CfnRoute(this, "Route", { apiId: this.api.apiId, - routeKey: `POST ${resolvedConfiguration.path}`, + routeKey: `${this.method} ${resolvedConfiguration.path}`, target: Fn.join("/", ["integrations", eventBridgeIntegration.ref]), authorizationType: "NONE", }); From 429a82b8e055d80a6af2afa078dc1ec0ab932b63 Mon Sep 17 00:00:00 2001 From: Sludge Date: Thu, 24 Aug 2023 13:53:38 +0100 Subject: [PATCH 2/4] Update documentation for webhooks to show new method option --- docs/webhook.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/webhook.md b/docs/webhook.md index 984919fa..038940e0 100644 --- a/docs/webhook.md +++ b/docs/webhook.md @@ -20,6 +20,7 @@ constructs: authorizer: handler: myAuthorizer.main path: /my-webhook-endpoint + method: POST plugins: - serverless-lift @@ -162,6 +163,23 @@ constructs: Always favor dynamic path selector to ensure the minimum amount of compute is executed downstream. The list of available dynamic selector is available in [API Gateway documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services.html#http-api-develop-integrations-aws-services-parameter-mapping). +### Method + +_Optional_ +Defaults to `POST` + +This is the HTTP method the webhook will accept. It can be any of the following: +- `POST` +- `PUT` +- `PATCH` + +```yaml +constructs: + stripe: + # ... + method: POST +``` + ## Extensions You can specify an `extensions` property on the webhook construct to extend the underlying CloudFormation resources. In the exemple below, the EventBridge Bus CloudFormation resource generated by the `stripe` webhook construct will be extended with the new `Name: StripeBus` CloudFormation property. From 9f79541b370990fc72d41fdbbb4b01e270e41372 Mon Sep 17 00:00:00 2001 From: Sludge Date: Thu, 24 Aug 2023 13:54:12 +0100 Subject: [PATCH 3/4] Switch webhook method over to be an enum instead of plain string field --- src/constructs/aws/Webhook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constructs/aws/Webhook.ts b/src/constructs/aws/Webhook.ts index cfb1fd78..4759f2c8 100644 --- a/src/constructs/aws/Webhook.ts +++ b/src/constructs/aws/Webhook.ts @@ -28,7 +28,7 @@ const WEBHOOK_DEFINITION = { insecure: { type: "boolean" }, path: { type: "string" }, eventType: { type: "string" }, - method: { type: "string" }, + method: { enum: ["POST", "PUT", "PATCH"] }, }, required: ["path"], additionalProperties: false, From aa7931e75bd77bc11f153f9cfdfa15e359a9c561 Mon Sep 17 00:00:00 2001 From: Sludge Date: Thu, 24 Aug 2023 13:54:52 +0100 Subject: [PATCH 4/4] Add in tests for webhook method option --- test/fixtures/webhooks/serverless.yml | 18 ++++++++++++++++++ test/unit/webhooks.test.ts | 10 ++++++++++ 2 files changed, 28 insertions(+) diff --git a/test/fixtures/webhooks/serverless.yml b/test/fixtures/webhooks/serverless.yml index f585d0e9..cbd4b72f 100644 --- a/test/fixtures/webhooks/serverless.yml +++ b/test/fixtures/webhooks/serverless.yml @@ -24,3 +24,21 @@ constructs: bus: Properties: Name: myBus + post: + type: webhook + authorizer: + handler: authorizer.main + path: /post + method: POST + put: + type: webhook + authorizer: + handler: authorizer.main + path: /put + method: PUT + patch: + type: webhook + authorizer: + handler: authorizer.main + path: /patch + method: PATCH diff --git a/test/unit/webhooks.test.ts b/test/unit/webhooks.test.ts index aefc140f..2e357d44 100644 --- a/test/unit/webhooks.test.ts +++ b/test/unit/webhooks.test.ts @@ -21,6 +21,16 @@ describe("webhooks", () => { }); }); + test.each([ + ["post", "POST"], + ["put", "PUT"], + ["patch", "PATCH"], + ])("%p webhook should have method %p", (useCase, expectedMethod) => { + expect(cfTemplate.Resources[computeLogicalId(useCase, "Route")]["Properties"]).toMatchObject({ + RouteKey: expectedMethod + " /" + expectedMethod.toLowerCase(), + }); + }); + it("allows overriding webhook properties", () => { expect(cfTemplate.Resources[computeLogicalId("extendedWebhook", "Bus")].Properties).toMatchObject({ Name: "myBus",