我使用AWS API Gateway创建了一个API。端点之一将消息写入SQS队列。内容是由映射模板创建的JSON。 API端点(POST)在主体中以JSON形式接收有效负载。我需要API参数以及Lambda函数中的主体。我使用SQS来确保每个事务最终都由Lambda函数处理。因此,我在API网关中设计了映射模板,如下所示:
#set($inputRoot = $input.path('$'))
#set($allParams = $input.params())
Action=SendMessage&MessageBody={"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"context" : {
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"api-key" : "$context.identity.apiKey",
"authorizer-principal-id" : "$context.authorizer.principalId",
"caller" : "$context.identity.caller",
"cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
"cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
"cognito-identity-id" : "$context.identity.cognitoIdentityId",
"cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
"domain" : "$context.domainName",
"http-method" : "$context.httpMethod",
"stage" : "$context.stage",
"source-ip" : "$context.identity.sourceIp",
"user" : "$context.identity.user",
"user-agent" : "$context.identity.userAgent",
"user-arn" : "$context.identity.userArn",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath"
}, "body": $input.body}
如果然后使用主体中的有效JSON调用API,则会将其作为有效JSON添加到我的SQS队列中:
{"params" : {
"path" : {
"userid" : "4711"
}
, "querystring" : {
}
, "header" : {
"Accept" : "*\/*"
, "Accept-Encoding" : "gzip, deflate, br"
, "CloudFront-Forwarded-Proto" : "https"
, "CloudFront-Is-Desktop-Viewer" : "true"
, "CloudFront-Is-Mobile-Viewer" : "false"
, "CloudFront-Is-SmartTV-Viewer" : "false"
, "CloudFront-Is-Tablet-Viewer" : "false"
, "CloudFront-Viewer-Country" : "DE"
, "Content-Type" : "application\/json"
, "Host" : "api.example.com"
, "Postman-Token" : "62c71606-13df-4b52-b772-594fa0af5ced"
, "Referer" : "http:\/\/api.example.com\/dev\/queue\/sqs\/4711"
, "User-Agent" : "PostmanRuntime\/7.25.0"
, "Via" : "1.1 90cf045072333c2f671297de3161846f.cloudfront.net (CloudFront)"
, "X-Amz-Cf-Id" : "6lB7_0-mbznpoTWPc_ba0ngmaJ0VUTEUsSDwISO0YTgwoJMZ4D170g=="
, "X-Amzn-Trace-Id" : "Root=1-5ee0cd7b-45119685e51905886208e054"
, "X-Forwarded-For" : "130.100.136.74, 130.176.0.160"
, "X-Forwarded-Port" : "443"
, "X-Forwarded-Proto" : "https"
}
},
"context" : {
"account-id" : "",
"api-id" : "gufdrsc4x0",
"api-key" : "",
"authorizer-principal-id" : "",
"caller" : "",
"cognito-authentication-provider" : "",
"cognito-authentication-type" : "",
"cognito-identity-id" : "",
"cognito-identity-pool-id" : "",
"domain" : "api.example.com",
"http-method" : "POST",
"stage" : "dev",
"source-ip" : "160.100.136.74",
"user" : "",
"user-agent" : "PostmanRuntime/7.25.0",
"user-arn" : "",
"request-id" : "28b1201f-cf7d-45e5-8f57-6b54609a212e",
"resource-id" : "4yw0f8",
"resource-path" : "/queue/sqs/{userid}"
}, "body": {"order": {
"access_allowed": true,
"business_name": null,
"business_vat_number": null,
"buyer_address1": null,
"buyer_address2": null,
"buyer_city": null,
"buyer_country": "GB",
"buyer_email": "[email protected]",
"buyer_ip_address": "127.0.0.1",
"buyer_name": "Mr Buyer",
"buyer_postcode": null,
"buyer_region": null,
"cart": {
"cart_items": [
{
"download_attempts": 3,
"product": {
"id": 2811,
"license_type": "generated",
"member_types": [
"digital"
],
"name": "My Product",
"price": "£15.00",
"product_image_url": null,
"product_type": "digital",
"shopify_variant_id": null
},
"quantity": 1,
"tax_rate": 20.0,
"valid_until": "2016-02-04T10:59:25Z"
}
],
"completed_checkout_at": "2016-01-05T10:59:24Z"
},
"discount": null,
"dispatched_at": null,
"download_url": "http://transactions.sendowl.com/orders/123456/download/XXX",
"eu_resolved_country": "GB",
"eu_reverse_charge": null,
"for_subscription": false,
"gateway": "Stripe",
"gift_deliver_at": null,
"gift_order": false,
"giftee_email": null,
"giftee_name": null,
"id": "0000123456",
"licenses": [],
"order_custom_checkout_fields": [],
"paypal_email": null,
"price_at_checkout": "£15.00",
"receiver_email": "[email protected]",
"receiver_name": null,
"settled_affiliate_fee": "£5.00",
"settled_currency": "GBP",
"settled_gateway_fee": "£0.38",
"settled_gross": "£18.00",
"settled_tax": "£3.00",
"state": "complete",
"subscription_management_url": null,
"tag": null,
"transactions": [
{
"alternate_pay_method_note": null,
"created_at": "2016-01-05T10:59:24Z",
"gateway_transaction_id": "ch_fake001",
"net_price": "£15.60",
"payment_currency": "GBP",
"payment_gateway_fee": "£0.38",
"payment_gross": "£18.00",
"payment_tax": "£3.00",
"refund": false
}
],
"unsubscribe_url": "http://transactions.sendowl.com/orders/123456/unsubscribe/XXX",
"validity_statement": "This link may be used up to 3 times before 2016-02-04 10:59:25 UTC when it will expire."
}}}
然后,SQS会触发Lambda函数。该函数需要Records [0] ['body]中的数据。但是它似乎在SQS和Lambda之间被双重序列化了。所有条目都用引号(\“)引起来,使其无法读取,因为它始终以错误结尾。
{
"Records": [
{
"messageId": "67453c29-adf1-42c8-961d-d918ebbd6399",
"receiptHandle": "AQEBJV9TixAQQaFK2hx45pekrbWw4hwmNQedEsum5KtA2AcUn37pPFKvTsNq9zHMMsbMR7EwIAkvRLDjndLHt9JMqdQ/PHhNvNoL7Yqxi7kCROfUtwYdwLZNutUQpu7H1xUXZAy2fojsAP77ZfIt3366GikTKHYOf7tTHq0nxqW4wbI/z0tGr9tgEn6ux6xTbSZrLItqv4Y0Wi0GckkskOxch4EoibSEn10u+TdclIdhDwVkyEtJgvuExNQpKHsf+n9dZW/txw7pMweDIJXJz5CnhrNoWdxX/lHI4YpIvXqdJzR6BK4i3HOiEa3zJoQkX78BbQiqPjjZMQv+1JsPs7WzW7mkRTYl32PiBJi8T/1KXhjO2g5NsUUwi+jWmW2frjn/KhoACj7YttAWNMlJ79J4JULV7GDxJ5yAVwQWtGdnveE=",
"body": "{\"params\" : {\n \"path\" : {\n \"userid\" : \"4711\"\n }\n , \"querystring\" : {\n }\n , \"header\" : {\n \"Accept\" : \"*\\/*\"\n , \"Accept-Encoding\" : \"gzip, deflate, br\"\n , \"CloudFront-Forwarded-Proto\" : \"https\"\n , \"CloudFront-Is-Desktop-Viewer\" : \"true\"\n , \"CloudFront-Is-Mobile-Viewer\" : \"false\"\n , \"CloudFront-Is-SmartTV-Viewer\" : \"false\"\n , \"CloudFront-Is-Tablet-Viewer\" : \"false\"\n , \"CloudFront-Viewer-Country\" : \"DE\"\n , \"Content-Type\" : \"application\\/json\"\n , \"Host\" : \"api.example.com\"\n , \"Postman-Token\" : \"a6609489-c851-4a97-b488-cf8436d83330\"\n , \"Referer\" : \"http:\\/\\/api.example.com\\/dev\\/queue\\/sqs\\/4711\"\n , \"User-Agent\" : \"PostmanRuntime\\/7.25.0\"\n , \"Via\" : \"1.1 90cf045072373c2c672247de3161846f.cloudfront.net (CloudFront)\"\n , \"X-Amz-Cf-Id\" : \"GgzWFiE_xOfQs9y9_-_fa2BPPbpQYJPFp46wYaPNHTpX38MQUBj3UQ==\"\n , \"X-Amzn-Trace-Id\" : \"Root=1-5ee0cd1a-a87ed5a83be891c04c50bd0a\"\n , \"X-Forwarded-For\" : \"130.100.136.74, 130.176.0.156\"\n , \"X-Forwarded-Port\" : \"443\"\n , \"X-Forwarded-Proto\" : \"https\"\n }\n },\n \"context\" : {\n \"account-id\" : \"\",\n \"api-id\" : \"gupxrscxx0\",\n \"api-key\" : \"\",\n \"authorizer-principal-id\" : \"\",\n \"caller\" : \"\",\n \"cognito-authentication-provider\" : \"\",\n \"cognito-authentication-type\" : \"\",\n \"cognito-identity-id\" : \"\",\n \"cognito-identity-pool-id\" : \"\",\n \"domain\" : \"api.example.com\",\n \"http-method\" : \"POST\",\n \"stage\" : \"dev\",\n \"source-ip\" : \"130.100.136.74\",\n \"user\" : \"\",\n \"user-agent\" : \"PostmanRuntime/7.25.0\",\n \"user-arn\" : \"\",\n \"request-id\" : \"762ff394-3bfc-476b-9544-dc10ccac29cd\",\n \"resource-id\" : \"4yw0f8\",\n \"resource-path\" : \"/queue/sqs/{userid}\"\n }, \"body\": {\"order\": {\r\n \"access_allowed\": true,\r\n \"business_name\": null,\r\n \"business_vat_number\": null,\r\n \"buyer_address1\": null,\r\n \"buyer_address2\": null,\r\n \"buyer_city\": null,\r\n \"buyer_country\": \"GB\",\r\n \"buyer_email\": \"[email protected]\",\r\n \"buyer_ip_address\": \"127.0.0.1\",\r\n \"buyer_name\": \"Mr Buyer\",\r\n \"buyer_postcode\": null,\r\n \"buyer_region\": null,\r\n \"cart\": {\r\n \"cart_items\": [\r\n {\r\n \"download_attempts\": 3,\r\n \"product\": {\r\n \"id\": 2811,\r\n \"license_type\": \"generated\",\r\n \"member_types\": [\r\n \"digital\"\r\n ],\r\n \"name\": \"My Product\",\r\n \"price\": \"£15.00\",\r\n \"product_image_url\": null,\r\n \"product_type\": \"digital\",\r\n \"shopify_variant_id\": null\r\n },\r\n \"quantity\": 1,\r\n \"tax_rate\": 20.0,\r\n \"valid_until\": \"2016-02-04T10:59:25Z\"\r\n }\r\n ],\r\n \"completed_checkout_at\": \"2016-01-05T10:59:24Z\"\r\n },\r\n \"discount\": null,\r\n \"dispatched_at\": null,\r\n \"download_url\": \"http://transactions.sendowl.com/orders/123456/download/XXX\",\r\n \"eu_resolved_country\": \"GB\",\r\n \"eu_reverse_charge\": null,\r\n \"for_subscription\": false,\r\n \"gateway\": \"Stripe\",\r\n \"gift_deliver_at\": null,\r\n \"gift_order\": false,\r\n \"giftee_email\": null,\r\n \"giftee_name\": null,\r\n \"id\": \"0000123456\",\r\n \"licenses\": [],\r\n \"order_custom_checkout_fields\": [],\r\n \"paypal_email\": null,\r\n \"price_at_checkout\": \"£15.00\",\r\n \"receiver_email\": \"[email protected]\",\r\n \"receiver_name\": null,\r\n \"settled_affiliate_fee\": \"£5.00\",\r\n \"settled_currency\": \"GBP\",\r\n \"settled_gateway_fee\": \"£0.38\",\r\n \"settled_gross\": \"£18.00\",\r\n \"settled_tax\": \"£3.00\",\r\n \"state\": \"complete\",\r\n \"subscription_management_url\": null,\r\n \"tag\": null,\r\n \"transactions\": [\r\n {\r\n \"alternate_pay_method_note\": null,\r\n \"created_at\": \"2016-01-05T10:59:24Z\",\r\n \"gateway_transaction_id\": \"ch_fake001\",\r\n \"net_price\": \"£15.60\",\r\n \"payment_currency\": \"GBP\",\r\n \"payment_gateway_fee\": \"£0.38\",\r\n \"payment_gross\": \"£18.00\",\r\n \"payment_tax\": \"£3.00\",\r\n \"refund\": false\r\n }\r\n ],\r\n \"unsubscribe_url\": \"http://transactions.sendowl.com/orders/123456/unsubscribe/XXX\",\r\n \"validity_statement\": \"This link may be used up to 3 times before 2016-02-04 10:59:25 UTC when it will expire.\"\r\n}}}",
"attributes": {
"ApproximateReceiveCount": "1",
"AWSTraceHeader": "Root=1-5ee0cd1a-a87ed5a83be891c04c50bd0a",
"SentTimestamp": "1591790874414",
"SenderId": "AROAQJKS37YHIYFTSUYVY:BackplaneAssumeRoleSession",
"ApproximateFirstReceiveTimestamp": "1591790874421"
},
"messageAttributes": {},
"md5OfBody": "965d776c1cbbbcbf669fde368a1d73f8",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:eu-central-1:047118021238:Example-Test",
"awsRegion": "eu-central-1"
}
]
}
如何避免体内的转义(双序列化)数据? Lambda正在运行Python 3.8。还是有可能“修复” Python中的主体?
根据评论。解决方案是使用:
body=json.loads(event['Records'][0]['body'])