|
1 | 1 | 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'; |
2 | 4 | import { Construct } from 'constructs';
|
3 |
| -// import * as sqs from 'aws-cdk-lib/aws-sqs'; |
| 5 | +import { ICdkTsApiGatewayStackProps, IValidators } from '../bin/stack-config-types'; |
4 | 6 |
|
5 | 7 | export class CdkTsApiGatewayStack extends cdk.Stack {
|
6 |
| - constructor(scope: Construct, id: string, props?: cdk.StackProps) { |
| 8 | + constructor(scope: Construct, id: string, props: ICdkTsApiGatewayStackProps) { |
7 | 9 | super(scope, id, props);
|
8 | 10 |
|
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 | + }); |
10 | 21 |
|
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); |
15 | 133 | }
|
16 | 134 | }
|
0 commit comments