API GatewayからSQSのFIFOキューにメッセージをPOSTする

SQSのFIFOキューにAPI GatewayからメッセージをPOSTしてみました。FIFOキューで必要になるメッセージグループIDと重複削除IDの設定がポイントです。
2020.07.09

表題の構成を試す機会があったので、その手順をご紹介します。
(今回はコンソールでゴリゴリ作業していきます)

SQSの作成

まずはSQSのFIFOキューを作成しましょう。2020年7月9日にSQSもコンソールのデザインが新しくなり見やすくなりました。

01-make-sqs

キューに適当な名前を付けます。FIFOキューの場合は名前の最後に.fifoをつける必要がある点に注意しましょう。
また、今回は「コンテンツに基づく重複削除」にチェックを入れました。これで自動的にSQS側で重複削除IDを付与してくれます。重複削除IDを自分で付けたい場合は、このチェックを外しておきます。
(後はデフォルトで作成しました)

02-make-queue

FIFOキュー(myqueue.fifo)が作成できました。

03-complete-make-queue

API Gatewayに付与するIAM Roleの作成

次に、API GatewayからSQSへメッセージを送るためのIAMポリシーを作成します。
サービスはAPI Gatewayを選択してください。

04-select-service-iam

そのまま次に進みましょう。

05-next-step

ロールの作成画面はそのまま次に進みましょう。

06-next-step2

必要に応じてタグを付けてください。

07-next-step3

名前をつけてIAM Roleを作成します。

08-set-role-name

作成できたらSQSへメッセージを送るポリシーを作成して付与します。

09-remove-add

権限はsqs:SendMessageだけでいいので、下記のようなポリシーとなります。
(今回はビジュアルエディタで作りました。AWSアカウントIDとSQSリソースの名前はご自分のものに変えてください)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sqs:SendMessage",
            "Resource": "arn:aws:sqs:ap-northeast-1:[Your AWS Account ID]:myqueue.fifo"
        }
    ]
}

作成できました。

10-complete-make-iam-role

API Gatewayの作成

次にAPI Gatewayを作成しましょう。

11-make-api

今回は「REST API」を作ります。

12-select-rest-api

適当なAPI名を付けて作成しましょう。(ここではmysqsapi

13-make-api2

作成できたAPIに対して「リソースの作成」を行います。

14-make-resource

適当なリソース名を付けて作成します。(ここではenqueue

15-named-resource

つぎにメソッドを作成します。

16-make-method

メッセージをPOSTで送りたいので「POST」を選択しましょう。

17-select-post

チェックボタンを押して作成します。

18-checked

次に、各種パラメータを指定してメソッドのセットアップを行います。

設定項目 設定内容
統合タイプ AWSサービス
AWSリージョン ap-northeast-1(利用リージョンに合わせてください)
AWSサービス SQS
HTTPメソッド POST
アクションの種類 パス上書きの使用
パス上書き [対象のAWSアカウントID] / [送信先のキューの名前]
実行ロール API Gateway用に作成したIAM RoleのARN
コンテンツの種類 パススルー
デフォルトタイムアウトの使用 チェック(デフォルト)

上記の設定ができたら「保存」しておきましょう。

19-setup-post

次に「統合リクエスト」を設定します。

20-integration-request

まずはSQSへメッセージをPOSTするために「HTTPヘッダー」を設定します。

設定項目 設定内容
Content-Type 'application/x-www-form-urlencoded'

21-add-header

最後にマッピングテンプレートを追加します。
SQSの作成時に指定した通り、重複削除IDは自動で付与されますが、「メッセージグループIDは必須で、自分で付与する必要がある」ので、MessageGroupIdも受け取れるようにしておきましょう。
注:肝心のテンプレートの内容ですが実際は1行です。下記で2行になっているのは表示上の都合になります。

設定項目 設定内容
リクエスト本文のパススルー テンプレートが定義されていない場合(推奨)
Content-Type application/json
テンプレート Action=SendMessage&MessageGroupId=$input.params
('MessageGroupId')&MessageBody=$input.body

22-make-mapping-template

テストしてみる

一通り設定できたので、ここで早速テストしてみます。

23-test-post

「クエリ文字列」と「リクエスト本文」を次のように入力してテストします。
メッセージグループIDは、テストのために簡単な「group1」という名前にしました。

クエリ文字列

MessageGroupId=group1

リクエスト本文

{
	"data" : "test"
}

無事にメッセージが送れたら画面右側のようにMessageIdなどを含んだレスポンスが返ってきます。

24-test-post2

SQSのキューにメッセージが入っているか確認してみましょう。

25-check-sqs-queue

ポーリングしてみます。

26-polling

メッセージが入っているのが分かりますね。

27-checked-message

中身を確認してみましょう。メッセージグループIDが「group1」で入っていて、重複削除IDも自動で付与されています。

28-message-detail

本文も、先程送ったリクエストボディの中身が入っていますね。

29-message-body

せっかくなので、APIのデプロイまでやってみます。

30-deploy-api

適当なステージ名を付けてデプロイします。

31-named-depoy

デプロイできました。

32-deployed-api

デプロイしただけなのでどこからでもアクセスできる状態ですが、このAPIにメッセージを送ってみます。
今回はIoTデバイスからのデータを想定したものを送ってみました。

curl -H 'Content-Type:application/json' \
-X POST -d '{"led":"on", "temp":"27.2"}' \
https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/enqueue?MessageGroupId=group1

次のようなレスポンスが返ってくればOKです。(jqコマンドで整形したものになります)

{
  "SendMessageResponse": {
    "ResponseMetadata": {
      "RequestId": "bca777e2-0873-525d-bab0-20631bc11509"
    },
    "SendMessageResult": {
      "MD5OfMessageAttributes": null,
      "MD5OfMessageBody": "f00741b736a7f5bc40b9d3f343bbf2c4",
      "MD5OfMessageSystemAttributes": null,
      "MessageId": "59654fca-0c86-48fe-92a4-fab561399b5f",
      "SequenceNumber": "18854884546143471616"
    }
  }
}

先程と同様にSQS側も確認してみましょう。確かに送ったデータが届いていることを確認できました。

33-curl-post

参考にしたページ

今回はFIFO自体の動作検証までは行っていません。SQSのFIFOの詳細は下記の記事が分かりやすいです。

マッピングテンプレート作成時に、SQSへPOSTリクエストする詳細を確認するのに参考にしました。

SQSのFIFO機能は東京リージョンでも使えます。

最後に

API Gatewayから標準キューへ送るための情報はいくつか出てきますが、FIFOキューへ送るときの手順がなかったのでご紹介してみました。(やることはほとんど変わりませんが…)

なお、FIFOキューは標準キューよりもパフォーマンス要件が異なるため、ユースケースを見極めて採用いただければと思います。

この記事がどなたかのお役に立てれば幸いです。