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()
});
}