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

如何为AWS::Serverless::Api的GET查询参数添加高级验证?

实现AWS API Gateway查询参数高级验证的方法

问题根源

你当前使用的aws_proxy集成模式会让API Gateway直接将请求转发给Lambda,跳过所有基于OpenAPI Schema的高级参数校验,仅会检查参数是否存在。这就是你定义的minimum、enum等规则不生效的核心原因。

解决方案

方案1:改用非Proxy集成模式

如果不需要完整的请求上下文转发,可以将集成类型改为aws而非aws_proxy,这样API Gateway会严格执行你在OpenAPI Schema中定义的所有校验规则:

x-amazon-apigateway-integration:
  credentials: !Ref APIGatewayRole
  httpMethod: "POST"
  uri:
    Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SearchFunction.Arn}/invocations"
  passthroughBehavior: "when_no_match"
  type: "aws" # 替换aws_proxy为aws
  requestTemplates:
    application/json: |
      {
        "text": "$input.params('text')",
        "page": $input.params('page'),
        "hitsPerPage": $input.params('hitsPerPage'),
        "subscription": "$input.params('subscription')",
        "distributionTenant": "$input.params('distributionTenant')"
      }

这种方式下,API Gateway会自动校验查询参数的类型、最小值、枚举值等,不符合规则的请求会直接返回400错误,无需Lambda处理。

方案2:在Lambda函数内实现参数校验

如果必须使用aws_proxy模式(比如需要完整的请求上下文),可以在Lambda函数内部添加参数校验逻辑,借助JSON Schema验证库实现:

以Python为例:

import jsonschema
from jsonschema import validate

def validate_query_params(params):
    # 转换字符串类型的数字参数为整数
    try:
        params["page"] = int(params["page"])
        params["hitsPerPage"] = int(params["hitsPerPage"])
    except (KeyError, ValueError):
        return False, "page或hitsPerPage必须为有效整数"

    schema = {
        "type": "object",
        "properties": {
            "text": {"type": "string"},
            "page": {"type": "integer", "minimum": 1},
            "hitsPerPage": {"type": "integer", "minimum": 1},
            "subscription": {"type": "string", "enum": ["PLUS", "FREE", "HD"]},
            "distributionTenant": {"type": "string", "minLength": 4}
        },
        "required": ["text", "page", "hitsPerPage", "subscription", "distributionTenant"]
    }
    try:
        validate(instance=params, schema=schema)
    except jsonschema.exceptions.ValidationError as err:
        return False, err.message
    return True, ""

def lambda_handler(event, context):
    query_params = event.get("queryStringParameters", {})
    valid, message = validate_query_params(query_params)
    if not valid:
        return {
            "statusCode": 400,
            "body": f"参数校验失败: {message}"
        }
    # 执行后续业务逻辑

方案3:使用API Gateway的Lambda请求验证器

创建专门的Lambda验证函数,通过API Gateway的请求验证器配置,在请求到达主Lambda前执行校验:

  1. 编写Lambda验证函数,逻辑同方案2的校验逻辑,校验通过返回{"isValid": true},失败返回{"isValid": false, "errorMessage": "具体错误信息"}
  2. 在CloudFormation的API定义中关联该验证器:
x-amazon-apigateway-request-validators:
  custom-param-validator:
    validateCustomRequest: true
x-amazon-apigateway-request-validator: "custom-param-validator"
x-amazon-apigateway-custom-authorizer:
  type: "REQUEST"
  authorizerUri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ParamValidatorFunction.Arn}/invocations"
  authorizerResultTtlInSeconds: 300

这种方式既保留aws_proxy模式,又能在API Gateway层面拦截无效请求。

注意事项

  • 方案1需要手动编写请求模板映射参数,无法直接获取完整请求上下文
  • 方案2和3需自行处理参数类型转换(API Gateway会将所有查询参数以字符串形式传递)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:53:14