API Gateway から SQS に連携してみた

# はじめに

API Gateway には、AWS Service の Integrate 機能があります。例えば、フロントエンドから API Gateway を通じて SQS にデータを格納した場合、API Gateway → Lambda → SQS という構成が考えられます。この構成でも問題はないのですが、よりシンプルに API Gateway → SQS といった形で直接 SQS にデータを格納できます。シンプルなアーキテクチャにすることで、より堅牢で安定したサービス提供に貢献できるメリットがあります。

今回の記事では、直接 API Gateway → SQS へデータを格納する構築手順を確認してみましょう。



# IAM Role の作成

まず、API Gateway に設定する IAM Role を作成していきます。IAM Role の作成画面で API Gateway を選択します。

![image-20220109203906856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c6e3adcf-088a-5baf-27e1-d22ca99a18bd.png)



そのまま Next を押します。

![image-20220109203951127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5a54c8f0-6528-c317-d3db-df2cb907b984.png)



また Next を押します。

![image-20220109204014227.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ed2021e5-6927-5d26-c7cd-f89d84fa49b7.png)



Role Name を入力して Create Role を押します。

![image-20220109204057045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e55e5185-b8fa-25de-ce8f-52559b37ddca.png)





Add inline policy を押します。

![image-20220109204148857.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ffd85e20-e6ab-f30f-96f7-e1b4bf06fcc6.png)



入力するポリシーは次のものを入れます。SQS へ SendMessage を出来るようにします。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sqs:SendMessage",
            "Resource": "*"
        }
    ]
}
```

![image-20220109204303602.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/9df9d32d-dde8-e136-6107-9e3ef5fc902a.png)





Create を押して、IAM Role を作成します。

![image-20220109204456215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/10592865-b124-d44f-34ea-5e9424edf081.png)



作成した IAM Role ARN は後ほど使うので、メモっておきます。

```
arn:aws:iam::xxxxxxxxxxxx:role/apigateway-sqs-test-role
```



# SQS キューの作成

次に SQS キューを作成します。 

![image-20220109203006331.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/28551073-cdc1-aa25-4675-32f84dcd3873.png)



パラメータを入力

- type : standard 
- 名前

![image-20220109203105915.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fc85e7cf-a317-c9d3-7f38-a5c990286b6f.png)



Default のまま

![image-20220109203150834.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4e79e791-c858-24c6-703a-b199a48f6199.png)



作成した IAM Role を指定して、API Gateway からこの Queue にデータを格納できるように指定

![image-20220109204701368.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3a945359-2d42-1a4a-932a-5f0954f20203.png)



そのほかは Default のまま Create を押します。

![image-20220109204749508.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/f7b8a080-8d4c-9186-a627-845d9396bb28.png)



SQS キューが作成されました。

![image-20220109205714591.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/226474d0-4095-6f3e-1cb4-3118d20b2450.png)



# API Gateway の作成

API Gateway を作成していきます。

![image-20220109205938302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/53c6d810-410a-cdf2-6415-4dceb92b502b.png)



REST API を選びます。

![image-20220109210010618.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d737f7d2-93dd-a0df-53d7-0c819473414e.png)



API Gateway の名前を入れます。

```
apigateway-sqs-test
```

![image-20220109210106723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a749ef07-1da2-0303-7e28-a2268bc5cb49.png)



API Gateway の編集画面で、 Create Resource を押します。

![image-20220109211136417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a934c65c-a1cb-909c-6629-4556caf98153.png)



適当な名前で Create を押します。

![image-20220109211222531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e8552cad-bf0e-4251-920e-4bdbe8845ba2.png)



作成したリソースに対して、Create Method を押します。

![image-20220109211244697.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fc7a3504-3038-bc4c-61a3-e03b4041aeae.png)



今回は POST を選択します。

![image-20220109211308274.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/57b59957-abf1-40e1-98b6-4fc6b8e20b5b.png)



パラメータを入れます。

- Integration Type : AWS Service を選ぶ
- AWS Service : SQS を選択
- Path override : [AWSアカウントID/SQSキューの名前] を入力

![image-20220109212000482.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/6efc1770-0ef1-fb3c-e7a9-24920aceb541.png)



Path Override に何を入力するべきか調べる方法を説明します。今回の記事は、SQS にデータを格納する `SendMessage` API を使っていくため、次の APO Reference Document を参照します。
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#API_SendMessage_Examples

この Document に、`SendMessage` を実行するSample が書かれています。この Sample の中に、`123456789012/MyQueue` と記載されていますが、この部分を Path Override で入力しています。SQS の場合は今回の記事の内容で問題ないですが、他のサービスの場合は、そのサービスに合わせた文字列を入力する必要があるので、適宜調べていきましょう。

![image-20220109214540727.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ecb258b3-b9a3-986a-7361-4f683f36e4c8.png)



設定後、 Integration Request を選びます。

![image-20220109212212040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ea9bef4a-872c-7d1e-be49-b42fa72ff37e.png)



HTTP Headers に次のパラメータを入れます。

```
Content-Type
'application/x-www-form-urlencoded'
```

![image-20220109212333851.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/dc230320-4d0e-af14-0c6c-4b3e84a6f778.png)



Mapping Templates の add を押します。

![image-20220109212537626.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2a2604bc-258d-440e-734f-fae3b8fc7d26.png)



`application/json` を入れます。

![image-20220109212607675.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e92ba24b-a2e9-9e89-88b0-a78ee8240022.png)



Mapping Template の値に、次の文字列を入れます。

- Action : SQS で `sendMessage` の API を使う
- MessageBody : `$input.body` を指定。API Gateway に渡された Body を、そのまま SQS に格納する

```
Action=SendMessage&MessageBody=$input.body
```

![image-20220109214821261.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/60760030-553e-5eac-5d07-3334271b079c.png)



この Mapping Template に入力する文字列ですが、該当する API の Document を見ながら組み立てることが出来ます。
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html

この Document に Sample があり、URL クエリーパラメータが載っています。この中に、`Action=SendMessage` だとか、`MessageBody=this+is` と書かれています。この部分を Mapping Template として文字列を組み立てていきます。

![image-20220109214736958.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e980de1f-61d3-36b2-7fa9-f3dfba48d4a4.png)



# API Gateway で TEST

ここまで設定すると、TEST が出来ます。TEST をクリックします。

![image-20220109213046130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/455c190c-d89a-c736-4740-d410204a1231.png)



Request Body に次の文字列を入れます。ここに入れた文字列が SQS に格納されます。

```
{
	"data" : "test"
}
```

![image-20220109214934913.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3ca865bd-cdfd-d6ed-49e8-3eda02ba8f1f.png)



Test を押して、実際に SQS にデータを格納します。

![image-20220109214953803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/34a96d20-ea9c-744a-23f0-0f7df82e98b2.png)



Response が 200 になります。

![image-20220109215049510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2dc3b70c-5109-fb84-fa47-a441c710423a.png)



SQS側でデータを確認していきましょう。SQS キューの画面で `Send and receive messages` を押します。

![image-20220109215306508.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/46e3f184-ae8d-dd8c-f32a-3129ded422b6.png)



Poll for messages を押して、SQS 上のメッセージを受信します。

![image-20220109215325865.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e22170ea-f853-dcbb-3649-3231d3d51ef6.png)



画像はいくつかのメッセージが表示されていますが、複数回 TEST しているためです。どれか適当に選びます。

![image-20220109215355562.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/ac3fe045-28ea-5416-2dc0-ae4b1c271bb6.png)



Body に、テストで入力した文字列が表示されていることが確認できます。

![image-20220109215413422.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/53a99626-a267-39a4-f80b-45af7e214e25.png)



# API Gateway Deploy

API Gateway で Deploy API を押して、実行できるようにしていきます。

![image-20220109215518922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/23ce5159-7329-c18c-e027-4cc87bf7ab94.png)



適当に名前を入れて Deploy を押します。

![image-20220109220212956.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/83416da2-a8f9-73ae-9e5b-8f64cf7bd2d7.png)



Deploy 完了です。Invoke URL が生成されています。

![image-20220109220244343.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a73c70b9-1a04-af07-e088-0167ba4ee27a.png)



# curl で TEST

これで外部から REST API 経由で SQS にデータを格納できるようになりました。今回は、curl コマンドでやっていきます。

```
curl -s -H 'Content-Type:application/json' \
-X POST \
https://uuy6eahto0.execute-api.ap-northeast-1.amazonaws.com/prod/sqs-queue \
-d '{"test1":"data1", "test2":"data2"}'
```



実行例

```
> curl -s -H 'Content-Type:application/json' \
      -X POST \
      https://uuy6eahto0.execute-api.ap-northeast-1.amazonaws.com/prod/sqs-queue \
      -d '{"test1":"data1", "test2":"data2"}' | jq .
{
  "SendMessageResponse": {
    "ResponseMetadata": {
      "RequestId": "4d17bbed-9166-5b96-adf1-e1b94eb7c5e4"
    },
    "SendMessageResult": {
      "MD5OfMessageAttributes": null,
      "MD5OfMessageBody": "58fdfbfc48f868b6b9c50b3e8aa09894",
      "MD5OfMessageSystemAttributes": null,
      "MessageId": "c21a633e-d8dc-4b0e-9f33-7b2b2d7595f9",
      "SequenceNumber": null
    }
  }
}
```



実行した結果を SQS 上でも確認できます。

![image-20220109220631049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b54e784b-790b-7d03-9188-4bbc5b21ab83.png)



curl で与えた body が確認できました。

![image-20220109220642981.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2eafc160-a122-46a8-c52d-6f916c7a8e5f.png)



# 検証を通じてわかったこと

- API Gateway で AWS Service Integrate をした時に、どういった API を呼びだすのか指定するのが、Mapping Template 
- Mapping Template の指定は、各サービスの API Reference を参照しながら埋めていくのがわかりやすい



# 参考URL

https://dev.classmethod.jp/articles/post-message-to-sqs-with-fifo-from-api-gateway/