Невозможно отправить большую полезную нагрузку на SNS topi c с API-шлюза - PullRequest
0 голосов
/ 06 апреля 2020

Я реализовал конечную точку шлюза API, которая отправляет сообщения в топологию SNS c при поступлении новых запросов. Обычно это работает отлично, за исключением случаев, когда я пытаюсь отправить большую полезную нагрузку на SNS topi c. В этом случае я получаю неверный запрос от SNS API, даже если я не превышаю ограничения и квоты SNS или API Gateway. Например, я получаю это сообщение, если отправлю следующую полезную нагрузку, которая будет состоять из 15k букв 'a' или если массив будет содержать около 8k целых чисел:

{"count": 1, "данные": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ....", "флаг": 1, "обр": 1 }

Как я понимаю причину такого поведения кроется в следующая строка кода в моем шаблоне CloudFormation:

integration.request.querystring.Message: "method.request.body"
integration.request.querystring.TopicArn: !Sub "'${some-topic-arn}'"

Согласно документации мы могли бы использовать body тип вместо querystring , но это не работает. Также я попытался использовать сопоставление шаблона запроса и отправить topicArn через строку запроса, а сообщение - через сопоставление шаблона. Но это тоже не работает.

Так может кто-нибудь сказать мне, что я делаю неправильно и как решить проблему с ошибкой ошибочного запроса при отправке большого полезного груза через HTTP-запрос POST?

Вот мой текущий шаблон CloudFormation: / v1 / someApiEndpoint: post: requestBody: content: application / json: схема: $ ref: "# / components / schemas / SomeApiModel" обязательная: истинные ответы: '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 topi c:

class SomeApiModel
{
  int count; 
  string data; 
  int flag;
  int[] arr;
}

1 Ответ

0 голосов
/ 08 апреля 2020

Хорошо, я понял.

После многих часов, потраченных на расследование, я наконец нашел проблему и исправил ее. Как было упомянуто Michael-sqlbot в следующем сообщении об интеграции API GW и SQS , нам нужно переопределить путь к конечной точке publs sh SNS. Кстати, спасибо, что вы спасли мою жизнь =)

В случае, если кто-то также наткнется на эту проблему, вот решение:

  1. Прежде всего. Замените свойство URI внутри x-amazon-apigateway-интеграции: раздел из этого:

uri:! Sub "arn: aws: apigateway: $ {AWS :: Region}: sns: action / Publi sh "`

to this:

uri:! Sub " arn: aws: apigateway: $ {AWS :: Region}: sns: path // "

Переопределит путь как

Удалить следующие две строки кода из раздела параметров запроса интеграции:
integration.request.querystring.Message: "method.request.body"
integration.request.querystring.TopicArn: !Sub "'${SomeTopicArn}'"
Поместите параметры TopicArn, Message и Action в шаблон запроса тела: requestTemplates:
application/json:
    !Sub Action=Publish&TopicArn=$util.urlEncode('${my-topic-arn}')&Message=$util.urlEncode($input.body)##

Вот полное определение шаблона 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)##

Обратите внимание на свойство Content-Type . Он должен быть окружен единичными квотами `` как одно слово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...