All files generic-rest-api-aws-integration.ts

100% Statements 18/18
100% Branches 8/8
100% Functions 3/3
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 1073x 3x 3x                                               3x                 6x 6x 6x 6x 6x         6x   6x 6x 6x   6x                             6x         6x                                                     6x       6x          
import * as cdk from '@aws-cdk/core';
import * as iam from '@aws-cdk/aws-iam';
import * as apigateway from '@aws-cdk/aws-apigateway';
 
export interface GenericRestApiAwsIntegrationProps {
  /**
   * The RestApi resource to which a method will be added and integrated with the AWS service
   */
  restApiResource: apigateway.Resource;
 
  /**
   * The status code returned by RestApi on a successful request
   *
   * @default "200"
   */
  successResponseStatusCode?: string;
 
  /**
   * The status code returned by RestApi on a failing request
   *
   * @default "503"
   */
  failureResponseStatusCode?: string;
 
}
 
export abstract class GenericRestApiAwsIntegration extends cdk.Construct {
  /** @returns RestApi::Method to which the AwsIntegration was integrated to */
  protected readonly restApiMethod: apigateway.Method;
 
  protected abstract configureAwsService(id:string, props: GenericRestApiAwsIntegrationProps) : void;
  protected abstract init(id:string, props: GenericRestApiAwsIntegrationProps) : void;
 
  // configured in init method of each implementation
  protected awsService: string
  protected integrationHttpVerb = 'POST'
  protected integrationPath = "/"
  protected requestTemplates: { [contentType: string]: string; } = {}
  protected successResponseTemplates: { [contentType: string]: string; } = {}
  protected failureResponseTemplates: { [contentType: string]: string; } = {}
 
  public readonly integrationRole: iam.IRole
 
  protected constructor(scope: cdk.Construct, id: string, props: GenericRestApiAwsIntegrationProps) {
    super(scope, id);
 
    this.init(id,props)
    this.integrationRole = this.addIntegrationRole(id)
    const awsIntegration = this.addIntegration(props)
 
    this.restApiMethod = props.restApiResource.addMethod(this.integrationHttpVerb, awsIntegration, {
      methodResponses: [{
        statusCode: props.failureResponseStatusCode || "503",
        responseModels: {
          "application/json": apigateway.Model.EMPTY_MODEL
        }
      }, {
        statusCode: props.successResponseStatusCode || "200",
        responseModels: {
          "application/json": apigateway.Model.EMPTY_MODEL
        }
      }
      ]
    })
 
    this.configureAwsService(id,props)
  }
 
  private addIntegration(props: GenericRestApiAwsIntegrationProps) {
 
    const awsIntegration = new apigateway.AwsIntegration({
      service: this.awsService,
      path: this.integrationPath,
      options: {
        credentialsRole: this.integrationRole,
        passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
        requestParameters: {
          "integration.request.header.Content-Type": "'application/x-www-form-urlencoded'"
        },
        // useful for working with these templates: http://mapping-template-checker.toqoz.net/
        // variable reference:  https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
        requestTemplates: this.requestTemplates,
        integrationResponses: [
          {
            statusCode: props.failureResponseStatusCode || "503",
            responseTemplates: this.failureResponseTemplates,
            // https://docs.aws.amazon.com/apigateway/api-reference/resource/integration-response/#selectionPattern
            selectionPattern: "" // --> this is the default response
          },
          {
            selectionPattern: "200",
            statusCode: props.successResponseStatusCode || "200",
            responseTemplates: this.successResponseTemplates
          }
        ]
      }
    })
    return awsIntegration
  }
 
  private addIntegrationRole(id: string) {
    return new iam.Role(this, `${id}-${this.awsService}-integration-role`, {
      assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com')
    })
  }
}