のべラボ.blog

Tech Blog | AWS や サーバーレスやコンテナ などなど

Amazon SNS の ペイロードベースのメッセージフィルタリングを試してみる

従来、Amazon SNSサブスクリプションでは、メッセージの属性値ベースのフィルタリングは可能だったんですが、最近の Update でメッセージ本文、つまり『ペイロード』ベースのフィルタリングも可能になりました。

aws.amazon.com

下記の AWS ブログでは、AWS SAM テンプレートを使用してこの機能を試せるように解説してくれています。

aws.amazon.com

個人的には、この Update は大きい と感じています。

従来、他のアプリケーションやサービスに送信したいメッセージの本文に対してフィルタリングを設定したい場合は、Amazon EventBridge を使うことが多かったのですが、Amazon SNS でも可能になったので選択肢の幅が広がったといえます。例えば、シンプルに AWS Lambda 関数にメッセージを送信したいだけであれば、Amazon SNS の場合は通知件数に対する課金は無料になるので、コスト節減も期待できます。(データ転送容量に対する課金は発生します。)


では、今回は AWS マネジメントコンソール を使ってシンプルにこの機能を試していきます。

なお、ここで紹介する内容は、 2022年 11月 27日時点に確認した内容に基づきます。

今回は、Amazon SNS のサブスクライバーAmazon SQS の標準キューを使用する前提とします。

任意の名前で 標準キューを作成します。また、そのキューのアクセスポリシーに次ようなステートメント追加しておきます。(デフォルトのステートメントの変更や削除はしません。)

{
      "Sid": "__sns_statement",
      "Effect": "Allow",
      "Principal": {
        "Service": "sns.amazonaws.com"
      },
      "Action": "SQS:SendMessage",
      "Resource": "arn:aws:sqs:ap-northeast-1:123412341234:MyQueue"
    }

Resource: で指定するのは 作成した Amazon SQS のキューのARN なので、環境に応じて変更して下さい。

次に、Amazon SNS の 標準トピックを任意の名前で作成します。

続いて、その標準トピックのサブスクリプションを作成します。

サブスクリプションは、事前に作成しておいた Amazon SQS のキューを指定します。

その後は、いよいよフィルターの設定です。

次の図のように、[サブスクリプションポリシー] を展開表示して、[サブスクリプションフィルターポリシー]のトグルを ON にします。そして、[メッセージ本文]を選択します。

https://cdn-ak.f.st-hatena.com/images/fotolife/n/neob/20221127/20221127155830.png

[ JSON エディタ]にフィルターとなる JSON を指定しますが、今回はシンプルに下記のように設定しました。

{
  "test": [
    0,
    1,
    2
  ],
  "check": [
    "A",
    "B",
    "C"
  ]
}

このフィルターでは、メッセージは "test" キーと "check" キーを持ち、"test" キーは、0,1,2 のいずれかの値、"check"キーは、"A","B","C"のいずれかの値が条件になります。

ここまで設定出来たら、サブスクリプションの作成を完了します。

AWS マネジメントコンソールを使って、作成した標準トピックにメッセージを発行しましょう。

[件名]は任意の値を入力しますが、[本文]では、フィルターの条件にマッチするように次の JSON を入力します。

{
  "test": 0,
  "check":"A"
}

メッセージを発行した後、AWS マネジメントコンソールを使ってサブスクリプションに指定したAmazon SQS のキューのメッセージを受信してみましょう。1件、メッセージを受信しているはずです。メッセージの ID のリンクを選択して、送信したメッセージを受信できていることを確認しましょう。

また、他のメッセージも送信してみましょう。

例えば、次のメッセージだとフィルターの条件にマッチするので、キューでは受信されません。

{
  "test": 9,
  "check":"A"
}

次のメッセージも、フィルターの条件にマッチしません。

{
"test": 0
}

サブスクリプションのフィルターの内容を変更して色々試してみてもよいでしょう。 複雑なフィルターを記述することもできるので、次のドキュメントを参考にしてみて下さい!

docs.aws.amazon.com

/* -----codeの行番号----- */