Search code examples
amazon-web-servicesaws-api-gatewayaws-cdk

Adding request validator to API Gateway using AWS CDK


I am trying to perform request validation, specifically query parameter validation, on a GET request to AWS API gateway using AWS CDK:

const api = apigw.RestApi.fromRestApiAttributes(this, props.attributes.apiGatewayName, {
  restApiId: cdk.Fn.importValue('th-api-id'),
  rootResourceId: cdk.Fn.importValue('th-api-resource-id'),
});

api.root
  .resourceForPath("/trackCartons")
  .addMethod("GET", new apigw.LambdaIntegration(trackCartonsHandler), {
    requestParameters: {
      'method.request.querystring.cartonID': true
    },
    requestValidatorOptions: {
      validateRequestParameters: true,
    },
  });

Above code gives the error:

TypeError: this.api.addRequestValidator is not a function
    at Method.requestValidatorId (C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\node_modules\aws-cdk-lib\aws-apigateway\lib\method.js:1:5827)
    at new Method (C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\node_modules\aws-cdk-lib\aws-apigateway\lib\method.js:1:2701)        
    at Resource.addMethod (C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\node_modules\aws-cdk-lib\aws-apigateway\lib\resource.js:1:1188)
    at new CartonDeliveryStack (C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\lib\carton-delivery-stack.js:95:8)
    at Object.<anonymous> (C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\bin\carton-delivery.js:28:1)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)

Node.js v18.16.1

It also dumps the code of the path

C:\Users\Sushant Sinha\Desktop\aws\carton-delivery\node_modules\aws-cdk-lib\aws-apigateway\lib\method.js:1

to the console.

Without the validator, the API is working perfectly. I have made changes with "resourceForPath" changed to the "addResource" method, but other than that, the whole code seems the same as what is present on the internet.


Solution

  • Looking at the CDK documentation, it looks like the static RestApi.fromRestApiAttributes method returns the type IRestApi.

    The IRestApi interface does not define a addRequestValidator method - this is likely where the problem is coming from because it appears the CDK implementation of Method is attempting to use the addRequestValidator method.

    I would suggest to refactor your code if possible, so that instead of instantiating the RestApi from imported properties, you pass a reference to the RestApi construct via props. This does assume that your API is also defined in CDK from the same package, it's not clear from the question. Your new code might looks something like this:

    
    interface TrackCartonsApiProps {
        readonly api: RestApi
    }
    
    class TrackCartonsApi extends Construct {
        constructor(scope: Construct, id: string, props: TrackCartonsApiProps) {
            props.api.root
                .resourceForPath("/trackCartons")
                .addMethod("GET", new apigw.LambdaIntegration(trackCartonsHandler), {
                    requestParameters: {
                      'method.request.querystring.cartonID': true
                    },
                    requestValidatorOptions: {
                      validateRequestParameters: true,
                    },
                });
        }
    }
    
    

    From the construct or stack where your root api is defined:

    const api = ...
    
    const trackCartonsApi = new TrackCartonsApi(this, 'TrackCartonsApi', {
        api: api
    });