Edited at

API Gateway 経由で SQS へメッセージを送る


この記事について


  • API Gateway から SQS へメッセージを送る方法について書いた記事です。

  • API Gateway の AWS Proxy を使って、SQS の SendMessage API を呼び出します。 ※ MessageBody はクエリ文字列で指定します。

  • AWS Proxy を使って連携を行うため、AWS Lambda の出番はありません。


API Gateway の AWS Proxy って何?

API Gateway から Labmda 等を介さずに、直接 AWS API を呼び出しする機能です。

ドキュメントでは AWS 統合と表現されています。1

この機能を使用して、API Gateway から SQS に直接メッセージを送ってみます。


構築手順


1. 事前準備

SQS キューの作成、API Gateway の API 作成を済ませておきます。

API Gateway から SQS の SendMessage API を実行するため、API Gateway の実行ロールを作成しておきます。

リファレンスを見た感じ、ミニマムにポリシーを作る場合、sqs:SendMessage を Allow するよう設定すれば良さそうですね。2

サクッと試したい場合、AmazonSQSFullAccess というマネージドポリシーがあるので、それをアタッチしておきましょう。3


2. リソース作成

テキトーにリソースを作成します

011_create_resource.png

テキトーにパラメーターを設定します。

設定項目
内容

リソース名
Messages

リソースパス
/messages

012_submit_create_resource.png

設定したら「リソースの作成」ボタンをクリック


3. メソッドを作成

リソースに対するメソッドを作成します。

使用する SQS の API である SendMessage は POST リクエストになるので、それをパクって POST リクエストを作成しましょう。

013_create_method.png

メソッドを決めてチェックマークをクリック。

014_create_post.png


4. メソッドの設定

次は POST メソッドのセットアップ。

個人的に詰まったポイント。

015_post_setup.png

設定項目
内容
備考

統合タイプ
AWS サービス

AWS リージョン
ap-northeast-1
使用する SQS キューがあるリージョンを指定

AWS サービス
Simple Queue Service (SQS)
API Gateway からリクエストを行う AWS サービスを選択

HTTP メソッド
POST
使用する API の Reference で確認
または、AWS CLI コマンドに --debug を付与して、出力を確認

アクションの種類
パス上書きの使用

パス上書き
000000000000/hello-sqs
AWS アカウント ID / SQS キュー名

実行ロール
arn:aws:iam::000000000000:role/APIGatewayExecuteRole
事前準備で作成した IAM Role の ARN

コンテンツの処理
パススルー

SQS キューを作成すると https://sqs.[リージョン名].amazonaws.com/[AWS アカウント ID]/[SQS キュー名] といった形式で URL が生成されます。

その URL に API Gateway からリクエストを送信するため、上記設定が必要になります。


5. メソッドリクエスト、統合リクエストの設定

API Gateway から SQS キューに対してリクエストする設定を行いましたが、まだ具体的なパラメーターをどうするのか設定していません。

ここからパラメーターを設定していきます。

まずは、メソッドリクエストから。

0211_method_request.png

「メソッドリクエスト」をクリック

0212_method_request_detail.png

名前
必須

messagebody

※ 今回はリクエストの検証を設定していないので、「必須」の隣に警告マークみたいなのが表示されます。

リクエストの検証を設定する場合にはドキュメントを参考に。4

次は統合リクエストを設定していきます。

021_integration_request.png

「統合リクエスト」をクリック

022_integration_request_detail.png

URL クエリ文字列パラメーターを設定します

名前
マッピング元
備考

Action
'SendMessage'

MessageBody
method.request.querystring.messageBody

Action は SendMessage API を実行するのは固定なため、値は 'SendMessage' となります。

MessageBody はクライアントからクエリ文字列で受け取った値を割り当てます。

SendMessage API に対して、どのようなパラメーター指定が必要となるかはリファレンスを確認しましょう。5


メソッドをテスト

設定したメソッドが期待通りに動作するか、マネジメントコンソール上でテストします。

031_test.png

「テスト」をクリック。 ※ ブラウザを小さくしすぎてデザインが崩れ気味・・・

032_test_querystring.png

クエリ文字列だけ、下記のように指定します。

messageBody=sample-by-test

033_test_submit.png

「⚡テスト」をクリック

034_test_result.png

ステータスで 200 がレスポンスされていれば OK!

下記のような出力が得られました。(長い)

レスポンス本文

{

"SendMessageResponse": {
"ResponseMetadata": {
"RequestId": "72c4d154-6bd4-518d-99d3-85cd0ea92a3f"
},
"SendMessageResult": {
"MD5OfMessageAttributes": null,
"MD5OfMessageBody": "266b344e1859386c47c43bf2502e9d87",
"MessageId": "283178b3-0426-4501-aa98-f3fda899bb55",
"SequenceNumber": null
}
}
}

レスポンスヘッダー

{"X-Amzn-Trace-Id":"Root=1-5c1f633d-e97a52209ec49f5c90af34bd","Content-Type":"application/json"}

ログ

Execution log for request 7390005d-069d-11e9-82d4-530405135372

Sun Dec 23 10:28:13 UTC 2018 : Starting execution for request: 7390005d-069d-11e9-82d4-530405135372
Sun Dec 23 10:28:13 UTC 2018 : HTTP Method: POST, Resource Path: /messages
Sun Dec 23 10:28:13 UTC 2018 : Method request path: {}
Sun Dec 23 10:28:13 UTC 2018 : Method request query string: {messageBody=sample-by-test}
Sun Dec 23 10:28:13 UTC 2018 : Method request headers: {}
Sun Dec 23 10:28:13 UTC 2018 : Method request body before transformations:
Sun Dec 23 10:28:13 UTC 2018 : Endpoint request URI: https://sqs.ap-northeast-1.amazonaws.com/000000000000/hello-sqs?Action=SendMessage&MessageBody=sample-by-test
Sun Dec 23 10:28:13 UTC 2018 : Endpoint request headers: {Authorization=*****************************************************************************************************************************************************************************************************************************************e59251, X-Amz-Date=20181223T102813Z, x-amzn-apigateway-api-id=nv5czfh87a, Accept=application/json, User-Agent=AmazonAPIGateway_nv5czfh87a, X-Amz-Security-Token=AgoGb3JpZ2luEN7//////////wEaDmFwLW5vcnRoZWFzdC0xIoACHDO4wYBxissppT8Wv4s0qSjvQPfpcZMDFwA6KJA46SkxaHCpIFriU6kJcNU9tv8nyOBp7IPcE/uEOYITaEgpuVDCtkKt/kz4FEmRI0NSTDYRjRMihNzP2GM7ABx8qqz0sX0dz6DfMYnzY3BgeBuTzStL+RxY7RJ69XGpbZFNYWmQCqJcTDYfpgKEfS5EaL435fsm+dK2W73H+T5qaGSqrrt9dXzMBw2cDGZg0Eq2EmWIYfc/zQelql8Y57AmixUZCTMnAafKjLWTfsIIoKjQGit1a5gJTHKkl/WBkdvqu+xcKxbZSdeh4en3uI2dghI6b3Kh9uAnzMm4iO9WTsMkiyqKAwik//////////8BEAAaDDk5ODUwODIwMDU1OSIMiL9KQWCmDkkJ+MrKKt4CDvIhbUiHaLFv/sv5mDzyGPZZ+qA6I3wcCwrYqgay4UZMQiMIIQxwSZ9nLmhiP14v6zVzMyncXNwPi9tezC5wgB/fdqwlEe3+tQ2Ny/bNGwKItqndnnAvspBI1tcQbDVRXLR8b5 [TRUNCATED]
Sun Dec 23 10:28:13 UTC 2018 : Endpoint request body after transformations:
Sun Dec 23 10:28:13 UTC 2018 : Sending request to https://sqs.ap-northeast-1.amazonaws.com/000000000000/hello-sqs?Action=SendMessage&MessageBody=sample-by-test
Sun Dec 23 10:28:13 UTC 2018 : Received response. Integration latency: 32 ms
Sun Dec 23 10:28:13 UTC 2018 : Endpoint response body before transformations: {"SendMessageResponse":{"ResponseMetadata":{"RequestId":"72c4d154-6bd4-518d-99d3-85cd0ea92a3f"},"SendMessageResult":{"MD5OfMessageAttributes":null,"MD5OfMessageBody":"266b344e1859386c47c43bf2502e9d87","MessageId":"283178b3-0426-4501-aa98-f3fda899bb55","SequenceNumber":null}}}
Sun Dec 23 10:28:13 UTC 2018 : Endpoint response headers: {x-amzn-RequestId=72c4d154-6bd4-518d-99d3-85cd0ea92a3f, Date=Sun, 23 Dec 2018 10:28:13 GMT, Content-Type=application/json, Content-Length=276}
Sun Dec 23 10:28:13 UTC 2018 : Method response body after transformations: {"SendMessageResponse":{"ResponseMetadata":{"RequestId":"72c4d154-6bd4-518d-99d3-85cd0ea92a3f"},"SendMessageResult":{"MD5OfMessageAttributes":null,"MD5OfMessageBody":"266b344e1859386c47c43bf2502e9d87","MessageId":"283178b3-0426-4501-aa98-f3fda899bb55","SequenceNumber":null}}}
Sun Dec 23 10:28:13 UTC 2018 : Method response headers: {X-Amzn-Trace-Id=Root=1-5c1f633d-e97a52209ec49f5c90af34bd, Content-Type=application/json}
Sun Dec 23 10:28:13 UTC 2018 : Successfully completed execution
Sun Dec 23 10:28:13 UTC 2018 : Method completed with status: 200

動作確認ができたので、次はいよいよデプロイです。

ちなみに、上記ログが API Gateway の実行ログとなります。デプロイ後はステージ毎に設定が必要です。

クライアントから受け取ったリクエスト情報や、API Gateway での変換後の情報が記載されているので、デバッグやトラブルシュートで役に立ちます。6


API をデプロイ

「アクション」をクリックし、「API のデプロイ」をクリックします。

041_deploy.png

デプロイの設定を行います。

設定項目
内容
備考

デプロイされるステージ
[新しいステージ]

ステージ名
hello
任意

ステージの説明

任意

デプロイメントの説明

任意

042_deploy_detail.png

入力したら「デプロイ」をクリック。

043_deploy_result.png

これで無事 API がデプロイされました。

「URL の呼び出し」に API へのアクセス URL が記載されています。


URL の呼び出し: https://nv5czfh87a.execute-api.ap-northeast-1.amazonaws.com/hello


https://[API Gateway API ID].execute-api.[リージョン名].amazonaws.com/[ステージ名] というフォーマットですね。

次は実際にデプロイされた API をテストしてみます。


API をテスト

HTTP リクエストができれば良いので、シンプルに curl を使って API を呼び出してみます。

今までの設定状況はこんな感じ。

設定項目
内容

アクセス先
https://nv5czfh87a.execute-api.ap-northeast-1.amazonaws.com/hello

パス
/message

クエリ文字列
messageBody=sample-by-curl

メソッド
POST

実際にリクエストしてみましょう。

$ curl -X POST https://nv5czfh87a.execute-api.ap-northeast-1.amazonaws.com/hello/messages?messageBody=sample-by-curl

{"SendMessageResponse":{"ResponseMetadata":{"RequestId":"6abdd20b-6703-509d-8647-86920e8f1702"},"SendMessageResult":{"MD5OfMessageAttributes":null,"MD5OfMessageBody":"7b5d62b5e609a2e5767bf58aa408a4ac","MessageId":"1fe55fa7-fee0-4681-a5a8-6c136ade1732","SequenceNumber":null}}}

無事リクエストできているっぽいですね。

AWS CLI を使って、SQS キューからメッセージを取得してみましょう。

$ aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/000000000000/hello-sqs

{
"Messages": [
{
"MessageId": "83f2d4d0-91f5-415d-97e2-d3f517718f48",
"ReceiptHandle": "AQEBz8whWHFzsUx5lIJ/ICJDIH6IPmerbXNxhz9Pm4nx+D8Onm0KY/4jxNFKXsJWDeND8w2JKc6jUUMriMrumlIb88Nsqcqmjx9ARb66tMbq1b3F039V04f9SN0XwFXZvI9aCSWccgBE+LUgF6XZFSqjjwa7kPsz+5uZBFrR6fvMDcKFE/VSHvT5ylwMfgPVAkTB6iegUS721jOEqECNH7tIgNWZ93BxfG8lCaKoknHkOBp2xJftHZC4zlUwSJGmTpsHr7/sVB8//Y3uRVvuWNjjJsNsDrXVXIkqL+fEmNQ6THY6EB4Y+1UXYyg6rOizo08Ot+i5s4Kd/ya3GYm1Zsva+2QKutdmWtBPN1T75E32loBR2kks9NISMagjBuU3lA0L8J0uHQICLPiOGNHhrbmU1A==",
"MD5OfBody": "7b5d62b5e609a2e5767bf58aa408a4ac",
"Body": "sample-by-curl"
}
]
}

マネジメントコンソールからテストした際のメッセージや、curl で指定した messageBody を持つメッセージを取得できるかと思います。


クリーンアップ

作成した下記リソースを消しておきましょう。


  • API Gateway の API

  • API Gateway 実行ロールとして作成した IAM Role

  • SQS キュー


今回作成した API の swagger

API Gateway では、作成した API をエクスポートできます。7

今回作成した API を swagger yaml としてエクスポートした結果を記載しておきますので、構築が上手く行かなかった等あれば参考にどうぞ。

---

swagger: "2.0"
info:
version: "2018-12-23T10:40:52Z"
title: "MyAPI"
host: "nv5czfh87a.execute-api.ap-northeast-1.amazonaws.com"
basePath: "/hello"
schemes:
- "https"
paths:
/messages:
post:
produces:
- "application/json"
parameters:
- name: "messageBody"
in: "query"
required: true
type: "string"
responses:
200:
description: "200 response"
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
credentials: "arn:aws:iam::000000000000:role/APIGatewayExecuteRole"
uri: "arn:aws:apigateway:ap-northeast-1:sqs:path/000000000000/hello-sqs"
responses:
default:
statusCode: "200"
requestParameters:
integration.request.querystring.MessageBody: "method.request.querystring.messageBody"
integration.request.querystring.Action: "'SendMessage'"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws"
definitions:
Empty:
type: "object"
title: "Empty Schema"


感想

Lambda や Fargate といった汎用性の高いサーバーレスサービスを使用する機会は多いかと思いますが、それらを使わずにマネージドサービスでサーバーレス環境を構築できると嬉しいですね。

また、API Gateway + SQS の組み合わせは、以下のようなメリットがあるかなーと思います。


  • SPA 等のクライアントから API の呼び出し頻度をスロットリングによって抑制できる

  • 呼び出し状況を API Gateway の CloudWatch メトリクスでモニタリングできる


    • 4XXError, 5XXError, Count, IntegrationLatency, Latency 等の有用なメトリクスが多くて嬉しい8



  • API Gateway の実行ログを有効化することでリクエストのロギングができる

  • IAM や Cognito User Pool を使用して API 呼び出し権限を制御できる

ということで、割と実用的な組み合わせなんじゃないかなーと思いました。

API Gateway は名前から結構シンプルなサービスであるイメージを受けますが、様々な機能があり奥が深いサービスですね。