Amazon web services 无法从API网关向SNS主题发送大负载

Amazon web services 无法从API网关向SNS主题发送大负载,amazon-web-services,amazon-cloudformation,aws-api-gateway,amazon-sns,Amazon Web Services,Amazon Cloudformation,Aws Api Gateway,Amazon Sns,我已经实现了一个API网关端点,当新请求到来时,它会向SNS主题发送消息。一般来说,除了我试图向SNS主题发送大负载的情况外,它工作得非常好。在这种情况下,我收到了来自SNS API的错误请求,即使我没有超过SNS或API网关限制和配额。 例如,如果我将发送由15k个字母“a”组成的下一个有效负载,或者如果数组将包含约8k个整数,我将收到此消息: { “计数”:1, “数据”:“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

我已经实现了一个API网关端点,当新请求到来时,它会向SNS主题发送消息。一般来说,除了我试图向SNS主题发送大负载的情况外,它工作得非常好。在这种情况下,我收到了来自SNS API的错误请求,即使我没有超过SNS或API网关限制和配额。 例如,如果我将发送由15k个字母“a”组成的下一个有效负载,或者如果数组将包含约8k个整数,我将收到此消息:

{ “计数”:1, “数据”:“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, "旗帜":1,, “arr”: }

据我所知,这种行为的原因隐藏在我的CloudFormation模板的下一行代码中:

integration.request.querystring.Message: "method.request.body"
integration.request.querystring.TopicArn: !Sub "'${some-topic-arn}'"
根据上下文,我们可以使用body类型而不是querystring,但它不起作用。 此外,我还尝试使用请求模板映射,通过querystring发送topicArn,并通过模板映射发送消息。但它也不起作用

那么,有人能告诉我我做错了什么,以及如何解决通过HTTP POST请求发送大负载时出现错误请求的问题吗

以下是我当前的CloudFormation模板: /v1/s端点: 职位: 请求主体: 内容: 应用程序/json: 模式: $ref:“#/components/schemas/SomeApiModel” 必填项:true 响应: '200': 说明:“200响应”

            '500':
              description: "500 response"
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/ErrorMessage"

          x-amazon-apigateway-request-validator: "SomeApiModelValidator"
          x-amazon-apigateway-integration:
            type: "aws"
            httpMethod: "POST"
            uri: !Sub "arn:aws:apigateway:${AWS::Region}:sns:action/Publish"
            credentials: !GetAtt SomeApiRole.Arn
            responses:
              '2\d{2}':
                statusCode: 200
            requestParameters:
              integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
              integration.request.querystring.Message: "method.request.body"
              integration.request.querystring.TopicArn: !Sub "'${SomeTopicArn}'"
            passthroughBehavior: "NEVER"
            requestTemplates:
              application/json: |
               #set($input.path('$').payload = { "userIdentity": $util.parseJson($context.authorizer.userIdentity), "data": $util.parseJson($input.body) })
               #set($encodedJson = $util.urlEncode($input.json('$.payload')))
以下是我的模型定义,我将其发送到API网关,然后传输到SNS主题:

class SomeApiModel
{
  int count; 
  string data; 
  int flag;
  int[] arr;
}
好的,我知道了

经过长时间的调查,我终于找到了问题并解决了。 正如在下一篇文章中提到的,我们需要覆盖SNS发布端点的路径。 顺便说一句,谢谢你救了我的命=)

如果有人也会遇到这个问题,这里有一个解决方案:

  • 首先。从以下位置替换x-amazon-apigateway-integration:部分中的URI属性:
  • uri:!子“arn:aws:apigateway:${aws::Region}:sns:action/Publish”`

    为此:

    uri:!子“arn:aws:apigateway:${aws::Region}:sns:path/”

    它将根据需要覆盖路径

  • 从集成请求参数部分删除下面两行代码:
  • 将主题、消息和操作参数放入正文请求模板中: 请求模板:
  • 以下是此集成的完整CloudFormation模板定义:

                 x-amazon-apigateway-integration:
                    type: "aws"
                    httpMethod: "POST"
                    uri: !Sub "arn:aws:apigateway:${AWS::Region}:sns:path//"
                    credentials: !GetAtt my-personal-role.Arn
                    responses:
                      '2\d{2}':
                        statusCode: 200
                    requestParameters:
                      integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
                    passthroughBehavior: "NEVER"
                    requestTemplates:
                      application/json:
                        !Sub Action=Publish&TopicArn=$util.urlEncode('${my-topic-arn}')&Message=$util.urlEncode($input.body)##
    

    注意内容类型属性。它应该被单个配额包围,作为一个单词

    我遇到了同样的问题。对于requestTemplates,如何用在同一Clouformation YAML@Tequila中创建的SNS主题的arn替换${my topic arn}的值
    application/json:
        !Sub Action=Publish&TopicArn=$util.urlEncode('${my-topic-arn}')&Message=$util.urlEncode($input.body)##
    
                 x-amazon-apigateway-integration:
                    type: "aws"
                    httpMethod: "POST"
                    uri: !Sub "arn:aws:apigateway:${AWS::Region}:sns:path//"
                    credentials: !GetAtt my-personal-role.Arn
                    responses:
                      '2\d{2}':
                        statusCode: 200
                    requestParameters:
                      integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
                    passthroughBehavior: "NEVER"
                    requestTemplates:
                      application/json:
                        !Sub Action=Publish&TopicArn=$util.urlEncode('${my-topic-arn}')&Message=$util.urlEncode($input.body)##