AWS API Gateway Serverless 验证请求正文并返回错误消息作为响应

rDe*_*Dev 4 aws-lambda aws-api-gateway aws-serverless

我正在使用Serverless设置 AWS API Gateway 。理想情况下,不应使用 AWS 控制台进行任何配置,仅使用无服务器进行部署。

我想让它验证传入该项目中设置的各种 Lambda 函数的请求主体。应通过将收到的正文与关联的 JSON 模式文件进行比较来完成此验证。在请求格式不正确的情况下,我希望响应指出哪些属性丢失或类型错误。

我找到了serverless-reqvalidator-plugin来解决针对模式进行验证的问题。验证项在资源中进行描述,架构使用serverless-aws-documentation 插件与自定义部分中的验证项相关联,最后使用 reqValidatorName 属性将函数与函数部分中的验证对象相关联。 http 事件。理想情况下,在这里的某个地方,我想设置在发生错误时应在响应中返回什么消息。

// serverless.yml

resources:
   Resources:
      BodyValidation:  
         Type: "AWS::ApiGateway::RequestValidator"
         Properties:
           Name: 'BodyValidation'
           RestApiId: 
             Ref: ApiGatewayRestApi
           ValidateRequestBody: true
           ValidateRequestParameters: false
           /// Ideally, some property about how to dynamically return an error message for invalid requests would be here, or bellow

custom:
  documentation:
// --- cut out api info
    models:
      - name: BodyValidationRequest
        contentType: "application/json"
        schema: ${file(./SampleValidationRequest.json)}

functions:
   SampleValidationFunction:
      //--- cut handler info
       events: 
         - http: 
              //--- cut path and method info
              reqValidatorName: BodyValidation
              documentation: // --- cut documentation info


Run Code Online (Sandbox Code Playgroud)

我按照类似问题的答案的指示这样做了。我有兴趣在不依赖 reqvalidator 插件的情况下执行此操作,但在AWS API Gateway 文档中给出的示例中,它没有显示如何使用无服务器执行此操作。

在过去似乎是不可能的,但现在似乎是可能的。不过,我找不到任何严格使用 serverless.yml 的示例。

我正在 AWS 控制台和 Postman 中测试请求。作为示例,这是我正在测试的模式:

// SampleValidationRequest.json

{
  "type": "object",
  "properties" :{
    "name": {
      "type": "string"
    },
    "id": {
      "type": "number"
    }
  },
  "required": ["name", "id"]
}
Run Code Online (Sandbox Code Playgroud)

当发送的正文缺少参数时,例如 id :

{
    "name": "test"
}
Run Code Online (Sandbox Code Playgroud)

我在响应正文中收到

{
  "message": "Invalid request body"
}
Run Code Online (Sandbox Code Playgroud)

我希望它能说出类似我在查看 AWS 日志时看到的内容

{
  "message": "Request body does not match model schema for content type application/json: [object has missing required properties (["id"])]
}
Run Code Online (Sandbox Code Playgroud)

所以,总结一下:

1. 是否可以添加一些属性来动态解释响应消息中请求正文的问题?

2. 是否可以仅使用 AWS API 的无服务器设置而不是使用 reqvalidator 来根据架构验证请求正文?

小智 6

  1. 是否可以添加一些属性来动态解释响应消息中请求正文的问题?

在一定程度上。请参阅此线程:https ://github.com/serverless/serverless/issues/3896

您需要添加一个resource属性,serverless.yml如下所示:

resources:
  Resources:
    ApiGatewayRestApi:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Name: ${self:provider.stage}-${self:service}
    GatewayResponseResourceNotFound:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        ResponseType: BAD_REQUEST_BODY
        "StatusCode" : "422"
        ResponseTemplates:
          application/json: "{\"message\": \"$context.error.message\", \"error\": \"$context.error.validationErrorString\"}"
Run Code Online (Sandbox Code Playgroud)
  1. 是否可以仅使用 AWS API 的无服务器设置而不是使用 reqvalidator 来根据架构验证请求正文?

对的,这是可能的。确保您更新到最新版本的 Serverless,否则它将无法生成 API 网关模型。

这是一个适合我的设置:

    events:
      - http:
          path: my_method/
          method: post
          request:
            schema:
              application/json: ${file(validate_my_method.json)}
Run Code Online (Sandbox Code Playgroud)