constructor()

in source/infrastructure/lib/api.ts [74:189]


  constructor(scope: Construct, id: string, props: ApiConstructProps) {
    super(scope, id);

    const apiLogGroup = new LogGroup(this, 'Logs', {
      removalPolicy: RemovalPolicy.DESTROY,
      retention: RetentionDays.THREE_MONTHS
    });
    addCfnSuppressRules(apiLogGroup, [{
      id: 'W84', reason: 'CloudWatch Logs are already encrypted by default.'
    }]);

    const api = new RestApi(this, 'IoTDeviceSimulatorApi', {
      defaultCorsPreflightOptions: {
        allowOrigins: ['*'],
        allowHeaders: [
          'Authorization',
          'Content-Type',
          'X-Amz-Date',
          'X-Amz-Security-Token',
          'X-Api-Key'
        ],
        allowMethods: [
          'GET',
          'POST',
          'PUT',
          'DELETE',
          'OPTIONS'
        ],
        statusCode: 200
      },
      deploy: true,
      deployOptions: {
        accessLogDestination: new LogGroupLogDestination(apiLogGroup),
        accessLogFormat: AccessLogFormat.jsonWithStandardFields(),
        loggingLevel: MethodLoggingLevel.INFO,
        stageName: 'prod',
        tracingEnabled: true
      },
      description: 'IoT Device Simulator Rest API',
      endpointTypes: [EndpointType.REGIONAL]
    });
    this.apiEndpoint = `https://${api.restApiId}.execute-api.${Aws.REGION}.amazonaws.com/prod`;
    this.apiId = api.restApiId;

    const requestValidator = new RequestValidator(this, 'ApiRequestValidator', {
      restApi: api,
      validateRequestParameters: true,
      validateRequestBody: true
    });

    addCfnSuppressRules(api.node.findChild('Deployment') as Deployment, [{
      id: 'W68', reason: 'The solution does not require the usage plan.'
    }]);
    addCfnSuppressRules(api.node.findChild('DeploymentStage.prod') as Stage, [{
      id: 'W64', reason: 'The solution does not require the usage plan.'
    }]);

    /**
     * method options for all methods
     */
    const universalMethodOptions: MethodOptions = {
      authorizationType: AuthorizationType.IAM,
      methodResponses: [{
        statusCode: '200',
        responseModels: {
          'application/json': { modelId: 'Empty' }
        }
      }],
      requestParameters: { 'method.request.querystring.nextToken': false },
      requestValidator: requestValidator
    };

    /**
     * Integration for all resources
     */
    const universalIntegration = new Integration({
      type: IntegrationType.AWS_PROXY,
      integrationHttpMethod: 'POST',
      options: {
        contentHandling: ContentHandling.CONVERT_TO_TEXT,
        integrationResponses: [{ statusCode: '200' }],
        passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH
      },
      uri: `arn:${Aws.PARTITION}:apigateway:${Aws.REGION}:lambda:path/2015-03-31/functions/${props.microservicesLambda.functionArn}/invocations`
    });

    /**
     * simulation API
     * ANY /simulation
     * ANY /simulation/{simid}
     */
    const simulationResource = api.root.addResource('simulation');
    simulationResource.addMethod(
      'ANY',
      universalIntegration,
      universalMethodOptions
    );
    const simulationSimIdResource = simulationResource.addResource('{simid}');
    simulationSimIdResource.addMethod('ANY', universalIntegration, universalMethodOptions);

    /**
     * Devive Types API
     * ANY /devicetypes
     * ANY /devicetypes/{typeid}
     */
    const deviceTypesResource = api.root.addResource('devicetypes');
    deviceTypesResource.addMethod('ANY', universalIntegration, universalMethodOptions);
    const typeIdResource = deviceTypesResource.addResource('{typeid}');
    typeIdResource.addMethod('ANY', universalIntegration, universalMethodOptions);

    props.microservicesLambda.addPermission('ApiLambdaInvokePermission', {
      action: 'lambda:InvokeFunction',
      principal: new ServicePrincipal('apigateway.amazonaws.com'),
      sourceArn: api.arnForExecuteApi()
    });
  }