You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CDK中让HTTP API Gateway按端点拒绝格式错误的JSON?

解决方案:基于Lambda+TypeScript实现API Gateway请求参数校验

核心说明

TypeScript的Interface仅为编译时类型提示,运行时会被完全擦除,无法直接用于参数校验。需结合运行时校验逻辑,再通过Lambda返回对应状态码,让API Gateway透传给请求方。

具体实现步骤

1. 选择运行时校验方案

推荐使用轻量且TS友好的zod库,或手动编写校验函数,以下是zod的示例:

import { z } from "zod";
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";

// 定义参数校验规则(替代Interface的运行时校验)
const ExampleRequestSchema = z.object({
  username: z.string().min(1, "用户名不能为空"),
  age: z.number().int().positive("年龄必须是正整数"),
  email: z.string().email("邮箱格式不正确")
});

// 推导TS类型,保留编译时类型提示
type ExampleRequest = z.infer<typeof ExampleRequestSchema>;

2. Lambda中实现校验与响应逻辑

export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
  try {
    // 解析请求体
    const requestBody = JSON.parse(event.body || "{}");
    
    // 执行参数校验
    const validatedData = ExampleRequestSchema.parse(requestBody);
    
    // 执行业务逻辑
    return {
      statusCode: 200,
      body: JSON.stringify({ message: "请求成功", data: validatedData })
    };
  } catch (error) {
    // 捕获参数校验错误,返回400(符合HTTP状态码规范)
    if (error instanceof z.ZodError) {
      return {
        statusCode: 400,
        body: JSON.stringify({
          error: "参数格式错误",
          details: error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`)
        })
      };
    }
    
    // 其他服务端内部错误返回500
    return {
      statusCode: 500,
      body: JSON.stringify({ error: "服务端内部错误" })
    };
  }
};

3. CDK配置API Gateway(确保响应透传)

Lambda返回的statusCode会被API Gateway默认透传,若需规范响应模型,可通过CDK配置:

import { RestApi, LambdaIntegration } from 'aws-cdk-lib/aws-apigateway';
import { Function, Runtime, Code } from 'aws-cdk-lib/aws-lambda';
import { Stack, Construct, StackProps } from 'aws-cdk-lib';

export class ApiStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    
    // 创建Lambda函数
    const exampleLambda = new Function(this, 'ExampleLambda', {
      runtime: Runtime.NODEJS_18_X,
      code: Code.fromAsset('lambda'),
      handler: 'example.handler'
    });
    
    // 创建API Gateway
    const api = new RestApi(this, 'ExampleApi');
    
    // 配置/example端点与POST方法
    const exampleResource = api.root.addResource('example');
    exampleResource.addMethod('POST', new LambdaIntegration(exampleLambda), {
      methodResponses: [
        { statusCode: '200' },
        { statusCode: '400' },
        { statusCode: '500' }
      ]
    });
  }
}

关键注意事项

  • 避免误用Interface:TS Interface仅在编译时生效,无法实现运行时参数校验,必须搭配运行时逻辑。
  • 规范状态码:参数错误应返回400 Bad Request,而非500 Internal Server Error,符合HTTP协议语义。
  • CDK简化配置:API Gateway默认会透传Lambda的响应状态码,无需复杂映射即可直接返回给请求方。

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 06:16:07