AWS API-Gateway与SNS通信

ken*_*ken 16 amazon-web-services amazon-sns aws-api-gateway

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

在此输入图像描述

我已经单独测试了Lambda函数以及SNS和Lambda之间的pub/sub消息传递,但我正在努力使用API​​-Gateway进行SNS切换.文档很轻,但我现在假设的是必须在POST请求中发送以下属性:

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

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

  3. TopicArn:表示我们要发布的SNS主题.在我的设计中,这将是一个静态值/端点,所以我更喜欢Web客户端也不必通过它,但如果它更容易做到这一点也会很好.

我尝试了很多东西,但我只是卡住了.很想在某处找到一个好的代码示例,但任何帮助都会受到赞赏.


想要为我目前的尝试增加更多的背景:

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

标头变量 杰森的身体

这会导致以下错误消息:

{
   "Error": {
     "Code": "InvalidParameter",
     "Message": "Invalid parameter: TopicArn or TargetArn Reason: no value for required parameter",
     "Type": "Sender"
  },
  "RequestId": "b33b7700-e8a3-58f7-8ebe-39e4e62b02d0"
}
Run Code Online (Sandbox Code Playgroud)

错误似乎表明TopicArn参数没有发送到SNS,但我在API-Gateway中包含以下内容:

在此输入图像描述

Jac*_*AWS 9

我来自Api Gateway团队.

我相信发布API的HTTP请求有一些格式,但这是我先使用的格式:

AWS Region us-west-2

AWS Service sns

AWS子域

HTTP方法POST

行动发布

==查询字符串==

主题'foo'
消息'
bar'TopicArn'arn:aws:sns:us-west-2:xxxxxxxxxxxx:test-api'

这对我有用,可以发布消息.

如果你有进一步的麻烦,请告诉我.

插口

  • 如何将请求主体和请求中发送的参数映射到SNS的Subject,Message和TopicArn? (3认同)

小智 8

如果有人仍在寻找原始问题的解决方案,仅通过 API 网关将 JSON 请求正文代理到 SNS 主题,这是可能的。

按照 Ken 上面的描述创建网关。然后简单地将主体代理到集成请求的查询参数。您还可以在此处对 Subject、TopicArn 等进行硬编码,或使用JsonPath映射来自请求正文的那些

例如:

{
   //body
   "topic": "arn:aws:sns:1234567:topic"
}
Run Code Online (Sandbox Code Playgroud)

可以映射到标题为:

method.request.body.topic
Run Code Online (Sandbox Code Playgroud)


ken*_*ken 6

在使用AWS支持后,我最终确保了这一点.这是我的解决方案:

  • 首先,即使你发送了一个,POST你也无法像你期望的那样在邮件正文中发送JSON消息
  • 相反,您必须URL编码JSON并将其作为查询参数传递
  • 还要记住,您发送的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);
Run Code Online (Sandbox Code Playgroud)