Оставаться правильно концептуально ориентированным относительно инкапсуляции JSON здесь может быть немного сложно, потому что несколько сервисов взаимодействуют в каскаде.
Когда сервисы AWS взаимодействуют с функциями, развернутыми с использованием сред Lambda среды Node.js дляпоставляя события, они фактически предоставляют всю полезную нагрузку вызова в виде объекта JSON на проводе.Этот слой JSON на самом деле вас не интересует, потому что Lambda прозрачно разбирает его на правильный объект JavaScript и передает его вам как event
.
Когда интеграция SQS / Lambda агрегирует события, существуетявляется структурой события с внешним массивом Records
в объекте event
, и каждый член массива содержит свойства одного сообщения SQS, полученного из действия API SQS ReceiveMessages
.На этом уровне также есть сериализация JSON, но, опять же, она прозрачно обрабатывается, и то, что сделано, отменяется, поэтому это не представляет интереса.
(интеграция Lambda SQS фактически предоставляет вам группу скрытых,управляемые серверы, которые опрашивают очередь SQS, чтобы собрать эти сообщения и отправить их в Lambda как вызовы функций.)
Среди свойств каждого объекта в массиве Records
есть body
, который содержит строку сполезная нагрузка из сообщения SQS.
Если вы сами захватываете опубликованное вами сообщение SQS, это body
будет содержать в точности те байты тела сообщения, которые отправлены в SQS с SendMessage
вызов.Это было бы прозрачно.Что бы вы ни указали, это то, что вы получите, будь то обычный текст, Base-64, JSON, XML и т. Д.
Однако ... у вас есть очередь SQS, которая подписана на тему SNS,
При подключении SNS к SQS:
Сообщение Amazon SQS содержит тему и сообщение, которые были опубликованы в теме вместе с метаданными о сообщении в документе JSON.
https://docs.aws.amazon.com/sns/latest/dg/sns-sqs-as-subscriber.html
«Сообщение Amazon SQS», упомянутое выше, означает тело сообщения - и это то, что вы найдете в свойстве body
, например, event.Records[0].body
.
"Документ JSON" в body
фактически создается SNS.
Когда SNS доставляет сообщение в SQS, он добавляет слой инкапсуляции JSON в свой собственный вывод, поэтомучто другие свойства сообщения сохраняются, а не только полезная нагрузка тела (которую SNS вызывает Message
).
Таким образом, вы получаете здесь body
, предоставленный в SQS SNS, который SNS имеетзакодировано в JSON.Все, что вам нужно сделать, это проанализировать это в объект JavaScript, используя JSON.parse()
.
let incomingMessage = JSON.parse(event.Records[0].body);
let type = incomingMessage.Type;
console.log(type); // 'Notification'
Вы также можете обнаружить, что полезная нагрузка фактического сообщения SNS (сообщения SNS, полученного от SES) являетсяОбъект JSON также.В таком случае:
let message = JSON.parse(incomingMessage.Message);
Обратите внимание, что мы анализируем body
в объект, беря атрибут Message
из результирующего объекта - который является строкой, содержащей объект JSON -и разбор этого в другой объект.Сверху, то, что мы делаем, в строке выше, чтобы декодировать это самое внутреннее сообщение, эквивалентно этому - показано здесь для иллюстрации принципа:
let message = JSON.parse(JSON.parse(event.Records[0].body).Message);
Это может первоначально показаться вам довольносложный и запутанный, но есть веские причины, почему это необходимо.JSON поддерживает идеальное вложение других JSON и чистых циклов, не путая границы объектов.Оба SNS и SQS поддерживают доставку только текстовых символьных данных - в качестве полезной нагрузки ... поэтому SES создает JSON-представление того, что он хочет вам сообщить , и отправляет его в SNS ... затем SNS создаетJSON-представление того, что он должен вам сказать, и отправляет его в SQS ... так что есть два уровня сериализации JSON, которые вам, в конечном счете, нужно будет отменить для обработки уведомлений о событиях SES> SNS> SQS> Lambda.
В качестве напоминания:
JSON.stringify()
ожидает объект JavaScript, массив, строку, число, логическое значение или значение NULL и сериализует его в строку, содержащую JSON.Тип возвращаемого значения - строка.Это операция «закодировать», «сериализовать» или «преобразовать в JSON».
JSON.parse()
ожидает объект JSON, то есть строковую переменную, содержащую JSON, и преобразует его обратно в объект JavaScript,массив, строка, число, логическое значение или ноль.Тип возвращаемого значения зависит от того, что было преобразовано в строку JSON на самом внешнем уровне.Это операция «декодирования», «десериализации» или «из JSON».Если какие-либо строки в объекте JSON содержат JSON, декодирование не является рекурсивным.Они декодируются как строки, а не как объекты внутри, поэтому для получения доступа к объекту внутри как к объекту JavaScript необходим дополнительный слой JSON.parse()
к полученным строкам.