Skip to content

Commit e309b2e

Browse files
committed
first commit
1 parent 2d95e73 commit e309b2e

8 files changed

+7160
-25
lines changed

bin/cdk-ts-api-gateway.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,7 @@
22
import 'source-map-support/register';
33
import * as cdk from 'aws-cdk-lib';
44
import { CdkTsApiGatewayStack } from '../lib/cdk-ts-api-gateway-stack';
5+
import environmentConfig from './stack-config';
56

67
const app = new cdk.App();
7-
new CdkTsApiGatewayStack(app, 'CdkTsApiGatewayStack', {
8-
/* If you don't specify 'env', this stack will be environment-agnostic.
9-
* Account/Region-dependent features and context lookups will not work,
10-
* but a single synthesized template can be deployed anywhere. */
11-
12-
/* Uncomment the next line to specialize this stack for the AWS Account
13-
* and Region that are implied by the current CLI configuration. */
14-
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
15-
16-
/* Uncomment the next line if you know exactly what Account and Region you
17-
* want to deploy the stack to. */
18-
// env: { account: '123456789012', region: 'us-east-1' },
19-
20-
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
21-
});
8+
new CdkTsApiGatewayStack(app, 'CdkTsApiGatewayStack', environmentConfig);

bin/stack-config-types.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { StackProps } from 'aws-cdk-lib';
2+
3+
export interface ICdkTsApiGatewayStackProps extends StackProps {
4+
lambda: {
5+
name: string,
6+
desc: string,
7+
memory: number,
8+
timeout: number,
9+
},
10+
api: {
11+
name: string,
12+
desc: string,
13+
modelName: string,
14+
rootResource: string,
15+
},
16+
usageplan: {
17+
name: string,
18+
desc: string,
19+
limit: number,
20+
rateLimit: number,
21+
burstLimit: number
22+
},
23+
apiKey: {
24+
name: string,
25+
desc: string,
26+
},
27+
validators: {
28+
bodyValidator: IValidators,
29+
paramValidator: IValidators,
30+
bodyAndParamValidator: IValidators,
31+
}
32+
}
33+
34+
export interface IValidators {
35+
requestValidatorName:string,
36+
validateRequestBody: boolean,
37+
validateRequestParameters: boolean
38+
}

bin/stack-config.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { ICdkTsApiGatewayStackProps } from './stack-config-types';
2+
3+
const environmentConfig: ICdkTsApiGatewayStackProps = {
4+
tags: {
5+
Developer: 'Faruk Ada',
6+
Application: 'CdkTsApiGateway',
7+
},
8+
lambda: {
9+
name: 'demo-resolver',
10+
desc: 'Lambda resolver used for Api Gateway YouTube tutorial',
11+
memory: 256,
12+
timeout: 30,
13+
},
14+
api: {
15+
name: 'demo-rest-api',
16+
desc: 'Rest Api Gateway used for Api Gateway YouTube tutorial',
17+
modelName: 'DemoModel',
18+
rootResource: 'v1',
19+
},
20+
usageplan: {
21+
name: 'demo-usage-plan',
22+
desc: 'Usage plan used for Api Gateway YouTube tutorial',
23+
limit: 100, // per day
24+
rateLimit: 20,
25+
burstLimit: 10,
26+
},
27+
apiKey: {
28+
name: 'demo-api-key',
29+
desc: 'Api Key used for Api Gateway YouTube tutorial',
30+
},
31+
validators: {
32+
bodyValidator: {
33+
requestValidatorName: 'demo-body-validator',
34+
validateRequestBody: true,
35+
validateRequestParameters: false,
36+
},
37+
paramValidator: {
38+
requestValidatorName: 'demo-param-validator',
39+
validateRequestBody: false,
40+
validateRequestParameters: true,
41+
},
42+
bodyAndParamValidator: {
43+
requestValidatorName: 'demo-body-and-param-validator',
44+
validateRequestBody: true,
45+
validateRequestParameters: true,
46+
},
47+
}
48+
};
49+
50+
export default environmentConfig;

lib/cdk-ts-api-gateway-stack.ts

Lines changed: 125 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,134 @@
11
import * as cdk from 'aws-cdk-lib';
2+
import * as lambda from 'aws-cdk-lib/aws-lambda';
3+
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
24
import { Construct } from 'constructs';
3-
// import * as sqs from 'aws-cdk-lib/aws-sqs';
5+
import { ICdkTsApiGatewayStackProps, IValidators } from '../bin/stack-config-types';
46

57
export class CdkTsApiGatewayStack extends cdk.Stack {
6-
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
8+
constructor(scope: Construct, id: string, props: ICdkTsApiGatewayStackProps) {
79
super(scope, id, props);
810

9-
// The code that defines your stack goes here
11+
// Lambda for resolving API requests
12+
const resolver = new lambda.Function(this, 'LambdaResolver', {
13+
functionName: props.lambda.name,
14+
description: props.lambda.desc,
15+
handler: 'index.handler',
16+
code: new lambda.AssetCode('dist/src'),
17+
runtime: lambda.Runtime.NODEJS_18_X,
18+
memorySize: props.lambda.memory,
19+
timeout: cdk.Duration.seconds(props.lambda.timeout),
20+
});
1021

11-
// example resource
12-
// const queue = new sqs.Queue(this, 'CdkTsApiGatewayQueue', {
13-
// visibilityTimeout: cdk.Duration.seconds(300)
14-
// });
22+
const integration = new apigateway.LambdaIntegration(resolver);
23+
24+
// API Gateway RestApi
25+
const api = new apigateway.RestApi(this, 'RestAPI', {
26+
restApiName: props.api.name,
27+
description: props.api.desc,
28+
defaultCorsPreflightOptions: {
29+
allowOrigins: apigateway.Cors.ALL_ORIGINS,
30+
allowMethods: ['GET', 'POST', 'PATCH', 'DELETE']
31+
},
32+
});
33+
34+
// Request Validators
35+
const createValidator = (input: IValidators) => new apigateway.RequestValidator(
36+
this,
37+
input.requestValidatorName,
38+
{
39+
restApi: api,
40+
requestValidatorName: input.requestValidatorName,
41+
validateRequestBody: input.validateRequestBody,
42+
validateRequestParameters: input.validateRequestParameters,
43+
},
44+
);
45+
46+
const bodyValidator = createValidator(props.validators.bodyValidator);
47+
const paramValidator = createValidator(props.validators.paramValidator);
48+
const bodyAndParamValidator = createValidator(props.validators.bodyAndParamValidator);
49+
50+
// API Gateway Model
51+
const model = new apigateway.Model(this, 'Model', {
52+
modelName: props.api.modelName,
53+
restApi: api,
54+
schema: {
55+
type: apigateway.JsonSchemaType.OBJECT,
56+
required: ['name'],
57+
properties: {
58+
name: { type: apigateway.JsonSchemaType.STRING },
59+
},
60+
},
61+
});
62+
63+
// Root Resources
64+
const rootResource = api.root.addResource(props.api.rootResource);
65+
66+
// Open Resource and Methods
67+
const openResource = rootResource.addResource('open');
68+
69+
['GET', 'POST', 'PATCH', 'DELETE'].map((method) => {
70+
openResource.addMethod(method, integration, {
71+
operationName: `${method} Open Resource`,
72+
});
73+
});
74+
75+
// Secure Resources and Methods
76+
const secureResource = rootResource.addResource('secure');
77+
const paramResource = secureResource.addResource('{param}');
78+
79+
secureResource.addMethod('GET', integration, {
80+
operationName: 'Get Secure Resource',
81+
apiKeyRequired: true,
82+
});
83+
84+
secureResource.addMethod('POST', integration, {
85+
operationName: 'POST Secure Resource',
86+
apiKeyRequired: true,
87+
requestValidator: bodyValidator,
88+
requestModels: { 'application/json': model },
89+
});
90+
91+
['GET', 'DELETE'].map((method) => {
92+
paramResource.addMethod(method, integration, {
93+
operationName: `${method} Secure Param Resource`,
94+
apiKeyRequired: true,
95+
requestValidator: paramValidator,
96+
requestParameters: { 'method.request.path.param': true },
97+
});
98+
});
99+
100+
paramResource.addMethod('PATCH', integration, {
101+
operationName: 'PATCH Secure Param Resource',
102+
apiKeyRequired: true,
103+
requestValidator: bodyAndParamValidator,
104+
requestParameters: { 'method.request.path.param': true },
105+
requestModels: { 'application/json': model },
106+
});
107+
108+
// API Usageplan
109+
const usageplan = api.addUsagePlan('UsagePlan', {
110+
name: props.usageplan.name,
111+
description: props.usageplan.desc,
112+
apiStages: [{
113+
api: api,
114+
stage: api.deploymentStage,
115+
}],
116+
quota: {
117+
limit: props.usageplan.limit,
118+
period: apigateway.Period.DAY,
119+
},
120+
throttle: {
121+
rateLimit: props.usageplan.rateLimit,
122+
burstLimit: props.usageplan.burstLimit,
123+
},
124+
});
125+
126+
// API Key for authorization
127+
const apiKey = api.addApiKey('ApiKey', {
128+
apiKeyName: props.apiKey.name,
129+
description: props.apiKey.desc,
130+
});
131+
132+
usageplan.addApiKey(apiKey);
15133
}
16134
}

0 commit comments

Comments
 (0)