Skip to content

Commit c77536f

Browse files
authored
feat(pipes-targets): add API Gateway (#31954)
Add API Gateway REST API as a Pipes target. Original PR with community review from @nmussy: #30772
1 parent c789063 commit c77536f

File tree

17 files changed

+35067
-1
lines changed

17 files changed

+35067
-1
lines changed

packages/@aws-cdk/aws-pipes-targets-alpha/README.md

+46
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ For more details see the [service documentation](https://docs.aws.amazon.com/eve
2626
Pipe targets are the end point of an EventBridge Pipe. The following targets are supported:
2727

2828
* `targets.ApiDestinationTarget`: [Send event source to an EventBridge API destination](#amazon-eventbridge-api-destination)
29+
* `targets.ApiGatewayTarget`: [Send event source to an API Gateway REST API](#amazon-api-gateway-rest-api)
2930
* `targets.CloudWatchLogsTarget`: [Send event source to a CloudWatch Logs log group](#amazon-cloudwatch-logs-log-group)
3031
* `targets.EventBridgeTarget`: [Send event source to an EventBridge event bus](#amazon-eventbridge-event-bus)
3132
* `targets.KinesisTarget`: [Send event source to a Kinesis data stream](#amazon-kinesis-data-stream)
@@ -67,6 +68,51 @@ const pipe = new pipes.Pipe(this, 'Pipe', {
6768
});
6869
```
6970

71+
### Amazon API Gateway Rest API
72+
73+
A REST API can be used as a target for a pipe.
74+
The REST API will receive the (enriched/filtered) source payload.
75+
76+
```ts
77+
declare const sourceQueue: sqs.Queue;
78+
79+
const fn = new lambda.Function( this, 'MyFunc', {
80+
handler: 'index.handler',
81+
runtime: lambda.Runtime.NODEJS_LATEST,
82+
code: lambda.Code.fromInline( 'exports.handler = e => {}' ),
83+
});
84+
85+
const restApi = new api.LambdaRestApi( this, 'MyRestAPI', { handler: fn } );
86+
const apiTarget = new targets.ApiGatewayTarget(restApi);
87+
88+
const pipe = new pipes.Pipe(this, 'Pipe', {
89+
source: new SqsSource(sourceQueue),
90+
target: apiTarget,
91+
});
92+
```
93+
94+
The input to the target REST API can be transformed:
95+
96+
```ts
97+
declare const sourceQueue: sqs.Queue;
98+
99+
const fn = new lambda.Function( this, 'MyFunc', {
100+
handler: 'index.handler',
101+
runtime: lambda.Runtime.NODEJS_LATEST,
102+
code: lambda.Code.fromInline( 'exports.handler = e => {}' ),
103+
});
104+
105+
const restApi = new api.LambdaRestApi( this, 'MyRestAPI', { handler: fn } );
106+
const apiTarget = new targets.ApiGatewayTarget(restApi, {
107+
inputTransformation: pipes.InputTransformation.fromObject({ body: "👀" }),
108+
});
109+
110+
const pipe = new pipes.Pipe(this, 'Pipe', {
111+
source: new SqsSource(sourceQueue),
112+
target: apiTarget,
113+
});
114+
```
115+
70116
### Amazon CloudWatch Logs Log Group
71117

72118
A CloudWatch Logs log group can be used as a target for a pipe.

packages/@aws-cdk/aws-pipes-targets-alpha/lib/api-destination.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export interface ApiDestinationTargetParameters {
4343
}
4444

4545
/**
46-
* A EventBridge Pipes target that sends messages to an EventBridge API destination.
46+
* An EventBridge Pipes target that sends messages to an EventBridge API destination.
4747
*/
4848
export class ApiDestinationTarget implements ITarget {
4949
private destination: IApiDestination;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { IInputTransformation, IPipe, ITarget, TargetConfig } from '@aws-cdk/aws-pipes-alpha';
2+
import { IRestApi } from 'aws-cdk-lib/aws-apigateway';
3+
import { IRole, PolicyStatement } from 'aws-cdk-lib/aws-iam';
4+
5+
/**
6+
* API Gateway REST API target properties.
7+
*/
8+
export interface ApiGatewayTargetParameters {
9+
/**
10+
* The input transformation to apply to the message before sending it to the target.
11+
*
12+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pipes-pipe-pipetargetparameters.html#cfn-pipes-pipe-pipetargetparameters-inputtemplate
13+
* @default - none
14+
*/
15+
readonly inputTransformation?: IInputTransformation;
16+
17+
/**
18+
* The method for API Gateway resource.
19+
*
20+
* @default '*' - ANY
21+
*/
22+
readonly method?: string;
23+
24+
/**
25+
* The path for the API Gateway resource.
26+
*
27+
* @default '/'
28+
*/
29+
readonly path?: string;
30+
31+
/**
32+
* The deployment stage for the API Gateway resource.
33+
*
34+
* @default - the value of `deploymentStage.stageName` of target API Gateway resource.
35+
*/
36+
readonly stage?: string;
37+
38+
/**
39+
* The headers to send as part of the request invoking the API Gateway REST API.
40+
*
41+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pipes-pipe-pipetargethttpparameters.html#cfn-pipes-pipe-pipetargethttpparameters-headerparameters
42+
* @default - none
43+
*/
44+
readonly headerParameters?: Record<string, string>;
45+
46+
/**
47+
* The path parameter values used to populate the API Gateway REST API path wildcards ("*").
48+
*
49+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pipes-pipe-pipetargethttpparameters.html#cfn-pipes-pipe-pipetargethttpparameters-pathparametervalues
50+
* @default - none
51+
*/
52+
readonly pathParameterValues?: string[];
53+
54+
/**
55+
* The query string keys/values that need to be sent as part of request invoking the API Gateway REST API.
56+
*
57+
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pipes-pipe-pipetargethttpparameters.html#cfn-pipes-pipe-pipetargethttpparameters-querystringparameters
58+
* @default - none
59+
*/
60+
readonly queryStringParameters?: Record<string, string>;
61+
}
62+
63+
/**
64+
* An EventBridge Pipes target that sends messages to an EventBridge API destination.
65+
*/
66+
export class ApiGatewayTarget implements ITarget {
67+
private restApi: IRestApi;
68+
private restApiParameters?: ApiGatewayTargetParameters;
69+
private restApiArn: string;
70+
public readonly targetArn;
71+
72+
constructor(restApi: IRestApi, parameters?: ApiGatewayTargetParameters) {
73+
this.restApi = restApi;
74+
this.restApiParameters = parameters;
75+
76+
if (this.restApiParameters?.stage === undefined && this.restApi.deploymentStage === undefined) {
77+
throw Error('The REST API must have a deployed stage.');
78+
}
79+
80+
this.restApiArn = this.restApi.arnForExecuteApi(
81+
this.restApiParameters?.method,
82+
this.restApiParameters?.path || '/',
83+
this.restApiParameters?.stage || this.restApi.deploymentStage.stageName,
84+
);
85+
86+
this.targetArn = this.restApiArn;
87+
}
88+
89+
grantPush(grantee: IRole): void {
90+
grantee.addToPrincipalPolicy(new PolicyStatement({
91+
resources: [this.restApiArn],
92+
actions: ['execute-api:Invoke'],
93+
}));
94+
}
95+
96+
bind(pipe: IPipe): TargetConfig {
97+
if (!this.restApiParameters) {
98+
return {
99+
targetParameters: {},
100+
};
101+
}
102+
103+
return {
104+
targetParameters: {
105+
inputTemplate: this.restApiParameters.inputTransformation?.bind(pipe).inputTemplate,
106+
httpParameters: this.restApiParameters,
107+
},
108+
};
109+
}
110+
}

packages/@aws-cdk/aws-pipes-targets-alpha/lib/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './api-destination';
2+
export * from './api-gateway';
23
export * from './cloudwatch-logs';
34
export * from './event-bridge';
45
export * from './kinesis';

packages/@aws-cdk/aws-pipes-targets-alpha/rosetta/default.ts-fixture

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Fixture with packages imported, but nothing else
22
import * as cdk from 'aws-cdk-lib';
3+
import * as api from 'aws-cdk-lib/aws-apigateway';
34
import * as events from 'aws-cdk-lib/aws-events';
45
import * as kinesis from 'aws-cdk-lib/aws-kinesis';
56
import * as logs from 'aws-cdk-lib/aws-logs';

0 commit comments

Comments
 (0)