Amazon web services 与SNS通信的AWS API网关
我正在构建一个将由Lambda函数提供服务的API,但我需要这些API是异步的,因此,我使用“AWS服务代理”发布SNS消息,然后让Lambda函数订阅相关SNS主题,以便接收请求的传递,而不是将API网关直接连接到Lambda函数。下面是一张说明流程的图片: 我已经单独测试了Lambda函数以及SNS和Lambda之间的发布/订阅消息传递,但是我正在努力使用SNS切换的API网关。文档非常简单,但我现在假设在POST请求中必须发送以下属性:Amazon web services 与SNS通信的AWS API网关,amazon-web-services,amazon-sns,aws-api-gateway,Amazon Web Services,Amazon Sns,Aws Api Gateway,我正在构建一个将由Lambda函数提供服务的API,但我需要这些API是异步的,因此,我使用“AWS服务代理”发布SNS消息,然后让Lambda函数订阅相关SNS主题,以便接收请求的传递,而不是将API网关直接连接到Lambda函数。下面是一张说明流程的图片: 我已经单独测试了Lambda函数以及SNS和Lambda之间的发布/订阅消息传递,但是我正在努力使用SNS切换的API网关。文档非常简单,但我现在假设在POST请求中必须发送以下属性: 操作:API网关提供在UI中设置此操作,我已在发布
希望在我当前的尝试中添加更多的上下文: 我曾尝试发布我的API,并使用Postman尝试获得有效的响应。以下是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"
}
该错误似乎表明,TopicArn参数未发送到SNS,但我已在API网关中包含以下内容:
通过将Lambda函数配置为AWS服务代理,可以使用API网关异步调用Lambda函数。配置基本上与您在中看到的相同,只是Lambda调用的uri更改为而不是/invoke/我只是猜测(我自己没有尝试过),但我认为您没有正确发送消息 根据AWS在此的文档(),您需要以类似于
应用程序/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格式的,但仍然需要像表单字段一样进行编码(一个笨拙的类比:)
此外,根据commonparameters文档(),您还有一些额外的必填字段(通常的访问密钥、签名等)
您尚未指定编写API网关所用的语言-可能有一个AWS SDK供您使用,而不是尝试手动编写REST请求)。我来自API网关团队 我相信发布API的HTTP请求有几种格式,但我首先使用的是: AWS地区美国西部-2 AWS服务sns AWS子域 HTTP方法POST 行动发布 ==查询字符串== 主题“foo”
消息“bar”
TopicArn'arn:aws:sns:us-west-2:XXXXXXXXXX:TestAPI' 这对我发布消息起了作用 如果你还有麻烦,请告诉我
Jack在与AWS支持部门合作后,我最终实现了这一点。以下是我的解决方案:
- 首先,即使您发送的是
,您也无法像预期的那样在消息体中发送JSON消息POST
- 相反,您必须对JSON进行URL编码,并将其作为查询参数传递
- 还请记住,您发送的JSON应该以根对象
开始,在SNS世界中,这意味着“默认通道”default
- 然后,Lambda最终会检测到SNS事件,您还必须提取出大量噪声才能获取JSON消息。为此,我创建了以下在Lambda函数中使用的函数:
/**
*当在AWS中运行时,它通过SNS运行
*event wconfig.ich为事件数据添加了大量混乱,
*这将测试SNS数据,并在必要时进行规范化
*/
功能摘要SNS(e){
如果(如记录){
返回JSON.parse(decodeURIComponent(e.Records[0].Sns.Message)).default;
}否则{
返回e;
}
}
/**
*处理者
*这是lambda函数的入口点
*/
exports.handler=函数处理程序(事件、上下文){
parent.event=abstractSNS(event);
我想这样做:
WebApp-->网关-->Lambda(使用Boto3在SNS中发布)--->SNS-->Lambda
我认为,事情会更简单。如果有人仍在寻找原始问题的解决方案,仅通过API网关将JSON请求主体代理到SNS主题,这是可能的 按照Ken上面描述的创建网关。然后简单地将主体代理到。您也可以在此处硬编码主题、主题等,或者使用 例如:
{
//body
"topic": "arn:aws:sns:1234567:topic"
}
可以映射到标题,如下所示:
method.request.body.topic
还请记住参数区分大小写;我还收到了OP的错误:
“消息”:“无效参数:TopicArn或Targetran原因:所需参数没有值”
唯一的问题是参数的大小写敏感性(具体来说应该是:“TopicArn”和“Message”)。这些参数在方法执行|后集成请求部分的“Name”字段中设置
“Mapped from”的大小写很重要,因为它与通过方法请求配置发送的参数相匹配,但是发送到SNS的是“Integration Request”的“Name”字段,这就是我的错误所在
这里是一个逐步的步骤