2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SQS、SNS、SNS+SQSからのイベントを比較してみた

Posted at

はじめに

業務でLambdaと組み合わせてSQSやSNSをよく使うのですが、イベントを正しくハンドリングする必要があります。
イベントの構造についてドキュメント等があるかもしれませんが、検証した方が早いと思い、自分で検証環境を作って確認してみました。

概要

以下によるイベントの構造をLambdaでログ出力して検証します。

  • SQS
  • SNS
  • SNS + SQS

設定

Lambda

以下のLambdaを作成し、イベントをログ出力します。

index.js
exports.handler = async (event) => {
    console.log(`event: ${JSON.stringify(event)}`); 
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

IAM

LambdaがSQSのメッセージを受け取れるようにするために、Lambda作成時に自動生成されたロールに対して、AmazonSQSFullAccessとAmazonSNSFullAccessを付与します。

SQS

SQSを標準設定で作成し、先ほど作成したLambdaをトリガーに設定します。

SNS

SNSを標準設定で作成し、以下をサブスクリプションとして指定します。

  • 先ほど作成したSQS
  • 先ほど作成したLambda

検証結果

SQSの場合

SQSのコンソール画面からテストメッセージを送信してみます。

image.png

イベント内容

bodyのところに先ほど送ったメッセージTest messageが入るようです。

{
    "Records": [
        {
            "messageId": "xxx",
            "receiptHandle": "xxx",
            "body": "Test message",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1653699635640",
                "SenderId": "xxx",
                "ApproximateFirstReceiveTimestamp": "1653699635650"
            },
            "messageAttributes": {},
            "md5OfBody": "xxx",
            "eventSource": "aws:sqs",
            "eventSourceARN": "<arn_of_sqs>",
            "awsRegion": "ap-northeast-1"
        }
    ]
}

SNSの場合

以下のメッセージをSNSから送信

image.png

イベント内容

Subject: メッセージのタイトル
Message: メッセージの本文
MessageAttributes: メッセージ属性

{
    "Records": [
        {
            "EventSource": "aws:sns",
            "EventVersion": "1.0",
            "EventSubscriptionArn": "<arn_of_sns>",
            "Sns": {
                "Type": "Notification",
                "MessageId": "xxx",
                "TopicArn": "<arn_of_sns>",
                "Subject": "Test message from SNS - Title",
                "Message": "Test message from SNS - Raw message ",
                "Timestamp": "2022-05-28T01:13:53.904Z",
                "SignatureVersion": "1",
                "Signature": "xxx",
                "SigningCertUrl": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-xxx.pem",
                "UnsubscribeUrl": "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=<EventSubscriptionArn>",
                "MessageAttributes": {
                    "key1": {
                        "Type": "String",
                        "Value": "\"Value1\""
                    },
                    "Key2": {
                        "Type": "String",
                        "Value": "[\"Value2\", \"Value3\"]"
                    }
                }
            }
        }
    ]
}

SNS + SQSの場合

同様に、SNSから同じメッセージを送ります。

イベント内容

bodyの中にSNSのイベントが入るようです。SQSを経由するからっぽいですね。

{
    "Records": [
        {
            "messageId": "xxx",
            "receiptHandle": "xxx",
            "body": "{\n  \"Type\" : \"Notification\",\n  \"MessageId\" : \"xxx\",\n  \"TopicArn\" : \"<arn_of_sqs>\",\n  \"Subject\" : \"Test message from SNS - Title\",\n  \"Message\" : \"Test message from SNS - Raw message\",\n  \"Timestamp\" : \"2022-05-28T01:26:45.690Z\",\n  \"SignatureVersion\" : \"1\",\n  \"Signature\" : \"xxx\",\n  \"SigningCertURL\" : \"https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-xxx.pem\",\n  \"UnsubscribeURL\" : \"https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=<arn_of_sqs>\",\n  \"MessageAttributes\" : {\n    \"key1\" : {\"Type\":\"String\",\"Value\":\"\\\"Value1\\\"\"},\n    \"key2\" : {\"Type\":\"String.Array\",\"Value\":\"[\\\"Value2\\\", \\\"Value3\\\"]\"}\n  }\n}",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1653701205731",
                "SenderId": "xxx",
                "ApproximateFirstReceiveTimestamp": "1653701205742"
            },
            "messageAttributes": {},
            "md5OfBody": "xxx",
            "eventSource": "aws:sqs",
            "eventSourceARN": "<arn_of_sqs>",
            "awsRegion": "ap-northeast-1"
        }
    ]
}

bodyの中を整形してみると、以下のようになり、SNSから直接Lambdaにメッセージを送った時と同様になりました。

{
  "Type": "Notification",
  "MessageId": "xxx",
  "TopicArn": "<arn_of_sqs>",
  "Subject": "Test message from SNS - Title",
  "Message": "Test message from SNS - Raw message",
  "Timestamp": "2022-05-28T01:26:45.69Z",
  "SignatureVersion": "1",
  "Signature": "xxx",
  "SigningCertURL": "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-xxx.pem",
  "UnsubscribeURL": "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=<arn_of_sqs>",
  "MessageAttributes": {
    "key1": {
      "Type": "String",
      "Value": "\"Value1\""
    },
    "key2": {
      "Type": "String.Array",
      "Value": "[\"Value2\", \"Value3\"]"
    }
  }
}

まとめ

結論、以下それぞれでイベントの構造が異なることが分かりました。

  • SQS
  • SNS
  • SNS + SQS

これらを用いて開発する際はイベントの構造に注意するとよさそうです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?