16
14

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 5 years have passed since last update.

ServerlessAdvent Calendar 2018

Day 23

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

Last updated at Posted at 2018-12-23

この記事について

  • 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 は名前から結構シンプルなサービスであるイメージを受けますが、様々な機能があり奥が深いサービスですね。

  1. AWS 統合で API Gateway API をビルドする https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started-aws-proxy.html

  2. Amazon SQS API のアクセス権限: アクションとリソースのリファレンス https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-api-permissions-reference.html

  3. Amazon SQS でのアイデンティティベース (IAM) のポリシーの使用 https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-using-identity-based-policies.html#sqs-access-policy-aws-managed-policies

  4. API Gateway でリクエストの検証を有効化する https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-method-request-validation.html

  5. SendMessage https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html

  6. API Gateway の API ログ作成をセットアップする https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-logging.html

  7. API Gateway から API をエクスポートする https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-export-api.html

  8. Amazon API Gateway のディメンションおよびメトリクス https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-metrics-and-dimensions.html

16
14
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
16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?