私はLambda関数によってサービスされるAPIを構築していますが、APIゲートウェイをLambda関数に直接接続するのではなく、これらを非同期にする必要があります。「AWSサービスプロキシ」を使用して SNSメッセージをパブリッシュし、Lambda関数に関連するSNSトピックをサブスクライブさせて、リクエストの配信を受信します。フローを示す画像は次のとおりです。
私はLambda機能とSNSとLambdaの間のpub/subメッセージングを分離してテストしましたが、APIゲートウェイからSNSへのハンドオフに苦労しています。ドキュメントは非常に軽量ですが、私が現在想定しているのは、POSTリクエストで次の属性を送信する必要があることです。
Action:API-GatewayはこれをUIで設定することを提案し、Publish適切なSNSアクションであるアクション
Message:POSTメッセージの本文はJSONドキュメントである必要があります。Webクライアントによって渡され、 SNSへのゲートウェイを介してプロキシされます。
TopicArn:公開先のSNSトピックを示します。私の設計では、これは静的な値/エンドポイントになるので、Webクライアントもこれを渡す必要がないようにしたいのですが、これを行う方が簡単であれば問題ありません。
多くのことを試しましたが、行き詰まっています。どこかで良いコード例を見つけたいと思いますが、どんな助けでもいただければ幸いです。
私の現在の試みにもう少しコンテキストを追加したかった:
私は自分のAPIを公開し、Postmanを使用して有効な応答を取得しようとしました。これが郵便配達員の画面です(1つはヘッダー変数用、もう1つはJSON本文用)。
その結果、次のエラーメッセージが表示されます。
{
"Error": {
"Code": "InvalidParameter",
"Message": "Invalid parameter: TopicArn or TargetArn Reason: no value for required parameter",
"Type": "Sender"
},
"RequestId": "b33b7700-e8a3-58f7-8ebe-39e4e62b02d0"
}
エラーは、TopicArnパラメーターがSNSに送信されていないことを示しているようですが、API-Gatewayに以下を含めました:
AWSサポートと連携した後、私は最終的にこれを動作させることができました。これが私の解決策です:
POST
を送信している場合でも、not期待どおりにメッセージの本文でJSONメッセージを送信できますdefault
のルートオブジェクトで始まる必要があります。これは、SNSの世界では「デフォルトチャネル」を意味します/**
* When this is run in AWS it is run "through" a SNS
* event wconfig.ich adds a lot of clutter to the event data,
* this tests for SNS data and normalizes when necessary
*/
function abstractSNS(e) {
if (e.Records) {
return JSON.parse(decodeURIComponent(e.Records[0].Sns.Message)).default;
} else {
return e;
}
}
/**
* HANDLER
* This is the entry point for the lambda function
*/
exports.handler = function handler(event, context) {
parent.event = abstractSNS(event);
私はApi Gatewayチームの出身です。
Publish APIへのHTTPリクエストにはいくつかの形式があると思いますが、最初に使用した形式は次のとおりです。
AWSリージョンus-west-2
AWSサービスSNS
AWSサブドメイン
HTTPメソッドPOST
アクション公開
==クエリ文字列==
件名「foo」
メッセージ「バー」
TopicArn 'arn:aws:sns:us-west-2:xxxxxxxxxxxx:test-api'
これは私がメッセージを公開するのに役立ちました。
さらに問題が発生した場合はお知らせください。
ジャック
誰かがまだ元の問題の解決策を探している場合、JSONリクエストの本文をAPIゲートウェイのみを介してSNSトピックにプロキシすることは可能です。
ケンが上で説明したようにゲートウェイを作成します。次に、本体を 統合リクエストのクエリパラメータ にプロキシします。ここで、Subject、TopicArnなどをハードコードするか、または JsonPath を使用してリクエストの本文からそれらをマッピングすることもできます。
例えば:
{
//body
"topic": "arn:aws:sns:1234567:topic"
}
次のようにヘッダーにマッピングできます。
method.request.body.topic
私はそれを次のようにします:
WebApp-> Gateway-> Lambda(Boto3を使用してSNSで公開する)-> SNS-> Lambda
物事はもっと簡単になると思います。
私は推測しているだけです(自分で試したことがありません)が、メッセージを正しく送信していないと思います...
ここのAWSのドキュメント( http://docs.aws.Amazon.com/sns/latest/api/API_Publish.html )に基づいて、POST the次のようなapplication/x-www-form-urlencoded
エンコーディングのように見えるメッセージ:
POST http://sns.us-west-2.amazonaws.com/ HTTP/1.1
...
Action=Publish
&Message=%7B%22default%22%3A%22This+is+the+default+Message%22%2C%22APNS_SANDBOX%22%3A%22%7B+%5C%22aps%5C%22+%3A+%7B+%5C%22alert%5C%22+%3A+%5C%22You+have+got+email.%5C%22%2C+%5C%22badge%5C%22+%3A+9%2C%5C%22sound%5C%22+%3A%5C%22default%5C%22%7D%7D%22%7D
&TargetArn=arn%3Aaws%3Asns%3Aus-west-2%3A803981987763%3Aendpoint%2FAPNS_SANDBOX%2Fpushapp%2F98e9ced9-f136-3893-9d60-776547eafebb
&SignatureMethod=HmacSHA256
&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE
&SignatureVersion=2
&Version=2010-03-31
&Signature=vmqc4XRupKAxsDAdN4j4Ayw5LQljXMps3kss4bkDfCk%3D
&Timestamp=2013-07-18T22%3A44%3A09.452Z
&MessageStructure=json
つまり、メッセージ本文は、ブラウザがフォームデータをエンコードする方法に似ています。メッセージはJSON形式にすることができますが、フォームフィールドであるかのようにエンコードする必要があります(扱いにくい例え:))。
また、共通パラメーターのドキュメント( http://docs.aws.Amazon.com/sns/latest/api/CommonParameters.html )に基づいて、いくつかの追加の必須フィールド(通常のアクセスキー、署名など)。
API Gatewayを記述する言語を指定していません。手動でRESTリクエスト)を作成する代わりに、使用できるAWS SDKがあるかもしれません。
API Gatewayを使用して、AWSサービスプロキシとして設定することにより、Lambda関数を非同期で呼び出すことができます。設定は基本的には このGitHubサンプル と同じですが、Lambda呼び出しのURIが/ invoke /だけではなく / invoke-async / に変更される点が異なります。