AWS API-Gateway 与 SNS 通信 [英] AWS API-Gateway communicating to SNS

查看:18
本文介绍了AWS API-Gateway 与 SNS 通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个将由 Lambda 函数提供服务的 API,但我需要这些是异步的,所以我使用AWS 服务代理"来发布,而不是将 API 网关直接连接到 Lambda 函数 SNS 消息,然后让 Lambda 函数订阅相关的 SNS 主题,以便它接收请求的传递.这是一张说明流程的图片:

I am building an API which will be serviced by Lambda functions but I need these to be asynchronous so rather than connecting the API-Gateway directly to the Lambda function I'm using the "AWS Service Proxy" to publish SNS messages and then have the Lambda function subscribe to the relevant SNS topic so it receives delivery of the requests. Here's a picture which illustrates the flow:

我已经单独测试了 Lambda 函数以及 SNS 和 Lambda 之间的发布/订阅消息传递,但我在 API 网关到 SNS 切换方面遇到了困难.文档很简单,但我现在假设必须在 POST 请求中发送以下属性:

I have tested both the Lambda function in isolation as well pub/sub messaging between SNS and Lambda but I am struggling with the API-Gateway to SNS handoff. Documentation is quite light but what I am assuming right now is that the following attributes must be sent in the POST request:

  1. Action:API-Gateway 提供在 UI 中进行设置,我已经放入了 发布 操作,这是适当的 SNS 操作

  1. Action: the API-Gateway offers to set this in the UI and I have put in the Publish action which is the appropriate SNS action

Message:POST 消息的正文应该是一个 JSON 文档.它将由 Web 客户端传递并通过网关代理到 SNS.

Message: the body of the POST message should be a JSON document. It would be passed by the web client and proxied through the gateway to SNS.

TopicArn:表示我们要发布到的 SNS 主题.在我的设计中,这将是一个静态值/端点,因此我希望网络客户端也不必传递它,但如果这样做更容易,那也可以.

TopicArn: indicates the SNS topic that we're publishing to. In my design this would be a static value/endpoint so I'd prefer that the web-client not have to pass this too but if it were easier to do this that would be fine too.

我尝试了很多东西,但都被卡住了.很想在某处找到一个好的代码示例,但任何帮助都将不胜感激.

I have tried lots of things but am just stuck. Would love to find a good code example somewhere but any help at all would be appreciated.

想为我目前的尝试添加更多背景信息:

Wanted to add a little more context on my current attempt:

我尝试发布我的 API 并使用 Postman 尝试获得有效响应.这是邮递员屏幕(一个用于标头变量,一个用于 JSON 正文):

I have tried publishing my API and using Postman to try and get a valid response. Here's the postman screens(one for header vars, one for JSON body):

这会导致以下错误消息:

This results in the following error message:

{
   "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 中包含了以下内容:

the error seems to indicate that the TopicArn parameter is not being sent to SNS but I have included the following in API-Gateway:

推荐答案

在与 AWS 支持人员合作后,我最终使这个工作正常进行.这是我的解决方案:

I did eventually get this to work after working with AWS support. Here's my solution:

  • 首先,即使您正在发送 POST,您也不能像预期的那样在消息正文中发送 JSON 消息
  • 相反,您必须对 JSON 进行 URL 编码并将其作为查询参数传递
  • 还要记住,您发送的 JSON 应该以 default 的根对象开头,这在 SNS-world 中表示默认频道"
  • 然后,Lambda 最终会接收到 SNS 事件,您还必须抽象出很多噪音以获取您的 JSON 消息.为此,我创建了在我的 Lambda 函数中使用的以下函数:
  • First of all even though you're sending a POST you will not be able to send a JSON message in the body of the message as you might expect
  • Instead you must URL Encode the JSON and pass it as query parameter
  • Also remember that the JSON you send should start with a root object of default which in SNS-world means the "default channel"
  • Then, eventually Lambda picks up the SNS event you must also abstract away a lot of the noise to get at your JSON message. For this I created the following function that I use within my Lambda function:

/**
 * 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);

这篇关于AWS API-Gateway 与 SNS 通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆