Search code examples
typescriptaws-lambdaresponseaws-cdkapi-gateway

How Do I Ensure My HTTP API Gateway Rejects Incorrectly Formatted JSON Per Endpoint In The CDK?


Problem

API Gateway is currently accepting all JSON that is sent to it, returning a 200 response. This is not the preferred use case, and I'd like to create a per-endpoint opinion of what fields are required. Maybe, using Typescript Interface in the invoked lambda to throw a 500 response back.

Idea / Steps:

  1. Data is sent into the API Gateway endpoint "/example"
  2. The JSON is received by the invoked Lambda
  3. The lambda uses TypeScript Interface
  4. The JSON is found to be incorrectly formatted
  5. API Gateway sends the correct response code that informs the sender that required fields in the JSON have not been received OR are incorrect (e.g. number not string).

Note: I am building all resources in the CDK.


Solution

  • Typescript can't perform validations (or anything else) at run-time: your NodeJS Lambda handler doesn't speak types. It runs the compiled Javascript.

    If you want help with run-time JSON input validation, consider the popular JSON Schema, "a declarative language that allows you to annotate and validate JSON documents." A JSON Schema is similar to a TS interface. It is itself expressed as a JSON document.

    How you implement API Gateway request validation with JSON Schema is different for the two types of Lambda integration. The suggestions made by @Maurice and @JimsonJames use JSONSchema to define a request Model resource. You can do this with the CDK, but only when using the non-proxy integration.

    You are using the Lambda Proxy Integration. As such, your Lambda function must perform the validations itself. Define a JSON Schema document representing the expected shape and types. Use a validator package like ajv (92 million weekly downloads) in your Lambda handler to validate the incoming event against that schema. In case of validation failure, ajv can produce the error feedback you're looking for.

    // my-handler.ts
    
    const ajv = new Ajv()
    const validate = ajv.compile<MyData>(schema)