簡體   English   中英

AWS API-Gateway 與 SNS 通信

[英]AWS API-Gateway communicating to SNS

我正在構建一個將由 Lambda 函數提供服務的 API,但我需要這些是異步的,所以我使用“AWS 服務代理”來發布SNS 消息,而不是將 API 網關直接連接到 Lambda 函數Lambda 函數訂閱相關的 SNS 主題,以便接收請求的傳遞。 這是一張說明流程的圖片:

在此處輸入圖片說明

我已經單獨測試了 Lambda 函數以及 SNS 和 Lambda 之間的發布/訂閱消息傳遞,但我正在努力解決 API 網關到 SNS 切換的問題。 文檔很簡單,但我現在假設必須在 POST 請求中發送以下屬性:

  1. 操作:API-Gateway 提供在 UI 中進行設置,我已經放入了Publish操作,這是適當的 SNS 操作

  2. 消息:POST 消息的正文應該是一個 JSON 文檔。 它將由 Web 客戶端傳遞並通過網關代理到 SNS。

  3. TopicArn :表示我們要發布到的 SNS 主題。 在我的設計中,這將是一個靜態值/端點,所以我希望網絡客戶端也不必傳遞它,但如果這樣做更容易,那也很好。

我已經嘗試了很多東西,但只是卡住了。 很想在某處找到一個好的代碼示例,但任何幫助都將不勝感激。


想在我當前的嘗試中添加更多背景信息:

我嘗試發布我的 API 並使用 Postman 嘗試獲得有效響應。 這是郵遞員屏幕(一個用於標頭變量,一個用於 JSON 正文):

頭變量 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 中包含了以下內容:

在此處輸入圖片說明

我來自 Api Gateway 團隊。

我相信對 Publish API 的 HTTP 請求有幾種格式,但這是我首先使用的一種:

AWS 區域 us-west-2

AWS 服務 sns

AWS 子域

HTTP 方法 POST

行動發布

== 查詢字符串 ==

主題'富'
消息“酒吧”
TopicArn 'arn:aws:sns:us-west-2:xxxxxxxxxxxx:test-api'

這對我發布消息有用。

如果您還有其他問題,請告訴我。

傑克

如果有人仍在尋找原始問題的解決方案,僅通過 API 網關將 JSON 請求正文代理到 SNS 主題,這是可能的。

按照 Ken 上面的描述創建網關。 然后簡單地將主體代理到集成請求的查詢參數 您還可以在此處對 Subject、TopicArn 等進行硬編碼,或使用JsonPath映射來自請求正文的那些

例如:

{
   //body
   "topic": "arn:aws:sns:1234567:topic"
}

可以映射到標題為:

method.request.body.topic

在與 AWS 支持人員合作后,我最終確實做到了這一點。 這是我的解決方案:

  • 首先,即使您正在發送POST您也無法像預期的那樣在消息正文中發送 JSON 消息
  • 相反,您必須對 JSON 進行 URL 編碼並將其作為查詢參數傳遞
  • 還要記住,您發送的 JSON 應該以default的根對象開頭,這在 SNS-world 中表示“默認頻道”
  • 然后,最終 Lambda 獲取 SNS 事件,您還必須抽象出很多噪音才能獲得 JSON 消息。 為此,我創建了在我的 Lambda 函數中使用的以下函數:

 /** * 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 通過將 Lambda 函數配置為 AWS 服務代理來異步調用它。 配置與您在此 GitHub 示例中看到的基本相同,不同之處在於 Lambda 調用的 uri 更改為/invoke-async/而不僅僅是 /invoke/

我只是在猜測(我自己沒有嘗試過),但我認為您沒有正確發送消息......

根據此處的 AWS 文檔( http://docs.aws.amazon.com/sns/latest/api/API_Publish.html ),您需要在似乎是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 網關所用的語言 - 可能有一個可供您使用的 AWS 開發工具包,而不是嘗試手動編寫 REST 請求)。

我會這樣做:

WebApp --> 網關 --> Lambda(使用 Boto3 在 SNS 中發布) --> SNS -->Lambda

我想,事情會更簡單。

還要記住參數區分大小寫; 我還收到了 OP 的錯誤: "Message": "Invalid parameter: TopicArn or TargetArn Reason: no value for required parameter"

唯一的問題是參數區分大小寫(具體來說應該是:“TopicArn”和“Message”)。 這些設置在方法執行 | POST - 集成請求部分,在“名稱”字段中。

“映射自”的大寫很重要,它與從方法請求配置發送的參數相匹配,但發送到 SNS 的是“集成請求”的“名稱”字段,這就是我錯的地方.

在此處輸入圖片說明

這是一個分步指南,適用於在瀏覽上述答案后仍然無法弄清楚的人。 變量名稱區分大小寫,因此請確保您是准確的。

  1. 打開 Post 方法
    一種。 選擇方法請求
    更改請求驗證器以Validate body, query string parameters, and headers
    C。 展開 URL 查詢字符串參數
    d. 添加以下兩個查詢字符串參數
    名稱: TopicArn ----> 選擇必填
    名稱: Message -----> 選擇必填

  2. 返回 Post 方法並打開集成請求
    一種。 展開 URL 查詢字符串參數
    添加以下兩個查詢字符串參數
    名稱: TopicArn映射自: method.request.querystring.TopicArn
    名稱: Message映射自: method.request.querystring.Message

  3. 測試時,更改以下命令以匹配您的 SNS ARN 並將其放入查詢字符串中。
    TopicArn=arn:aws:sns:us-west-2:1234567890:SNSName&Message="Hello from API Gateway"

來源/更多信息:
API網關代理集成服務指南
SNS 發布方法文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM