Skip to content

Commit

Permalink
feat(events): API Gateway target (aws#13823)
Browse files Browse the repository at this point in the history
close aws#12708 

Added construct class of api gateway target .

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
hedrall authored and john-tipper committed May 10, 2021
1 parent b36fca8 commit a77523a
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 1 deletion.
44 changes: 44 additions & 0 deletions packages/@aws-cdk/aws-events-targets/README.md
Expand Up @@ -19,6 +19,7 @@ Currently supported are:
* [Start a CodePipeline pipeline](#start-a-codepipeline-pipeline)
* Run an ECS task
* [Invoke a Lambda function](#invoke-a-lambda-function)
* [Invoke a API Gateway REST API](#invoke-a-api-gateway-rest-api)
* Publish a message to an SNS topic
* Send a message to an SQS queue
* [Start a StepFunctions state machine](#start-a-stepfunctions-state-machine)
Expand Down Expand Up @@ -185,3 +186,46 @@ rule.addTarget(new targets.SfnStateMachine(stateMachine, {
deadLetterQueue: dlq,
}));
```

## Invoke a API Gateway REST API

Use the `ApiGateway` target to trigger a REST API.

The code snippet below creates a Api Gateway REST API that is invoked every hour.

```typescript
import * as iam from '@aws-sdk/aws-iam';
import * as sqs from '@aws-sdk/aws-sqs';
import * as api from '@aws-cdk/aws-apigateway';
import * as targets from "@aws-cdk/aws-events-targets";

const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.rate(cdk.Duration.minutes(1)),
});

const fn = new lambda.Function( this, 'MyFunc', {
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_12_X,
code: lambda.Code.fromInline( 'exports.handler = e => {}' ),
} );

const restApi = new api.LambdaRestApi( this, 'MyRestAPI', { handler: fn } );

const dlq = new sqs.Queue(stack, 'DeadLetterQueue');

rule.addTarget(
new targets.ApiGateway( restApi, {
path: '/*/test',
mehod: 'GET',
stage: 'prod',
pathParameterValues: ['path-value'],
headerParameters: {
Header1: 'header1',
},
queryStringParameters: {
QueryParam1: 'query-param-1',
},
deadLetterQueue: queue
} ),
)
```
123 changes: 123 additions & 0 deletions packages/@aws-cdk/aws-events-targets/lib/api-gateway.ts
@@ -0,0 +1,123 @@
import * as api from '@aws-cdk/aws-apigateway';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import { addToDeadLetterQueueResourcePolicy, bindBaseTargetConfig, singletonEventRole, TargetBaseProps } from './util';

/**
* Customize the API Gateway Event Target
*/
export interface ApiGatewayProps extends TargetBaseProps {

/**
* The method for api resource invoked by the rule.
*
* @default '*' that treated as ANY
*/
readonly method?: string;

/**
* The api resource invoked by the rule.
* We can use wildcards('*') to specify the path. In that case,
* an equal number of real values must be specified for pathParameterValues.
*
* @default '/'
*/
readonly path?: string;

/**
* The deploy stage of api gateway invoked by the rule.
*
* @default the value of deploymentStage.stageName of target api gateway.
*/
readonly stage?: string;

/**
* The headers to be set when requesting API
*
* @default no header parameters
*/
readonly headerParameters?: { [key: string]: (string) };

/**
* The path parameter values to be used to
* populate to wildcards("*") of requesting api path
*
* @default no path parameters
*/
readonly pathParameterValues?: string[];

/**
* The query parameters to be set when requesting API.
*
* @default no querystring parameters
*/
readonly queryStringParameters?: { [key: string]: (string) };

/**
* This will be the post request body send to the API.
*
* @default the entire EventBridge event
*/
readonly postBody?: events.RuleTargetInput;

/**
* The role to assume before invoking the target
* (i.e., the pipeline) when the given rule is triggered.
*
* @default - a new role will be created
*/
readonly eventRole?: iam.IRole;
}

/**
* Use an API Gateway REST APIs as a target for Amazon EventBridge rules.
*/
export class ApiGateway implements events.IRuleTarget {

constructor(public readonly restApi: api.RestApi, private readonly props?: ApiGatewayProps) {
}

/**
* Returns a RuleTarget that can be used to trigger this API Gateway REST APIs
* as a result from an EventBridge event.
*
* @see https://docs.aws.amazon.com/eventbridge/latest/userguide/resource-based-policies-eventbridge.html#sqs-permissions
*/
public bind(rule: events.IRule, _id?: string): events.RuleTargetConfig {
if (this.props?.deadLetterQueue) {
addToDeadLetterQueueResourcePolicy(rule, this.props.deadLetterQueue);
}

const wildcardCountsInPath = this.props?.path?.match( /\*/g )?.length ?? 0;
if (wildcardCountsInPath !== (this.props?.pathParameterValues || []).length) {
throw new Error('The number of wildcards in the path does not match the number of path pathParameterValues.');
}

const restApiArn = this.restApi.arnForExecuteApi(
this.props?.method,
this.props?.path || '/',
this.props?.stage || this.restApi.deploymentStage.stageName,
);
return {
...(this.props ? bindBaseTargetConfig(this.props) : {}),
arn: restApiArn,
role: this.props?.eventRole || singletonEventRole(this.restApi, [new iam.PolicyStatement({
resources: [restApiArn],
actions: [
'execute-api:Invoke',
'execute-api:ManageConnections',
],
})]),
deadLetterConfig: this.props?.deadLetterQueue && { arn: this.props.deadLetterQueue?.queueArn },
input: this.props?.postBody,
targetResource: this.restApi,
httpParameters: {
headerParameters: this.props?.headerParameters,
queryStringParameters: this.props?.queryStringParameters,
pathParameterValues: this.props?.pathParameterValues,
},
};
}

}

1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-events-targets/lib/index.ts
Expand Up @@ -12,4 +12,5 @@ export * from './state-machine';
export * from './kinesis-stream';
export * from './log-group';
export * from './kinesis-firehose-stream';
export * from './api-gateway';
export * from './util';
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-events-targets/package.json
Expand Up @@ -84,6 +84,8 @@
"@aws-cdk/assert-internal": "0.0.0"
},
"dependencies": {
"@aws-cdk/aws-apigateway": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/aws-codebuild": "0.0.0",
"@aws-cdk/aws-codepipeline": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
Expand All @@ -104,6 +106,8 @@
},
"homepage": "https://github.com/aws/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-apigateway": "0.0.0",
"@aws-cdk/aws-batch": "0.0.0",
"@aws-cdk/aws-codebuild": "0.0.0",
"@aws-cdk/aws-codepipeline": "0.0.0",
"@aws-cdk/aws-ec2": "0.0.0",
Expand Down Expand Up @@ -132,6 +136,7 @@
"docs-public-apis:@aws-cdk/aws-events-targets.SfnStateMachine.machine",
"docs-public-apis:@aws-cdk/aws-events-targets.SnsTopic.topic",
"docs-public-apis:@aws-cdk/aws-events-targets.SqsQueue.queue",
"docs-public-apis:@aws-cdk/aws-events-targets.ApiGateway.restApi",
"docs-public-apis:@aws-cdk/aws-events-targets.ContainerOverride",
"props-default-doc:@aws-cdk/aws-events-targets.ContainerOverride.environment",
"props-default-doc:@aws-cdk/aws-events-targets.EcsTaskProps.containerOverrides"
Expand Down

0 comments on commit a77523a

Please sign in to comment.