I process the HTTP POST from a service that does not support JSON (Mailgun). It appears if I create an AWS API GW for POST and pass this to an AWS Lambda function that the data must be in JSON. Other than trying to serialize the POST to JSON (which I would prefer not to), does anyone know if this is the case?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
I found a solution here, works for me.
https://forums.aws.amazon.com/thread.jspa?messageID=673012&tstart=0#673012
The following is from the original post for a complete answer.
Step-by-step instructions are as follows:
- Amazon API Gateway -> Click "Create API".
- API name = "myTestAPI", Clone from API = Do not clone from existing API, Description = "Test"
- Click "Create API".
- Click "Create Resource".
- Resource Name = "myTestInput", Resource Path = "mytestinput".
- Click "Create Resource".
- Click "Create Method".
- Select "POST" or "GET" as required and click the tick.
- Integration type = "Lambda function", pick region as appropriate, write code as appropriate to action / store form data.
- Click "Save", click "Ok" to grant permission.
- Click "Integration Request".
- Click "Mapping Templates".
- Click "Add mapping template".
- Content-Type is "application/x-www-form-urlencoded" and click the tick.
- Click "application/x-www-form-urlencoded".
- Click the pencil icon next to "Input passthrough".
- Select "Mapping template".
- Paste the following into the Template box:
--
## convert HTML POST data or HTTP GET query string to JSON ## get the raw post data from the AWS built-in variable and give it a nicer name #if ($context.httpMethod == "POST") #set($rawAPIData = $input.path('$')) #elseif ($context.httpMethod == "GET") #set($rawAPIData = $input.params().querystring) #set($rawAPIData = $rawAPIData.toString()) #set($rawAPIDataLength = $rawAPIData.length() - 1) #set($rawAPIData = $rawAPIData.substring(1, $rawAPIDataLength)) #set($rawAPIData = $rawAPIData.replace(", ", "&")) #else #set($rawAPIData = "") #end ## first we get the number of "&" in the string, this tells us if there is more than one key value pair #set($countAmpersands = $rawAPIData.length() - $rawAPIData.replace("&", "").length()) ## if there are no "&" at all then we have only one key value pair. ## we append an ampersand to the string so that we can tokenise it the same way as multiple kv pairs. ## the "empty" kv pair to the right of the ampersand will be ignored anyway. #if ($countAmpersands == 0) #set($rawPostData = $rawAPIData + "&") #end ## now we tokenise using the ampersand(s) #set($tokenisedAmpersand = $rawAPIData.split("&")) ## we set up a variable to hold the valid key value pairs #set($tokenisedEquals = []) ## now we set up a loop to find the valid key value pairs, which must contain only one "=" #foreach( $kvPair in $tokenisedAmpersand ) #set($countEquals = $kvPair.length() - $kvPair.replace("=", "").length()) #if ($countEquals == 1) #set($kvTokenised = $kvPair.split("=")) #if ($kvTokenised[0].length() > 0) ## we found a valid key value pair. add it to the list. #set($devNull = $tokenisedEquals.add($kvPair)) #end #end #end ## next we set up our loop inside the output structure "{" and "}" { #foreach( $kvPair in $tokenisedEquals ) ## finally we output the JSON for this pair and append a comma if this isn't the last pair #set($kvTokenised = $kvPair.split("=")) "$util.urlDecode($kvTokenised[0])" : #if($kvTokenised[1].length() > 0)"$util.urlDecode($kvTokenised[1])"#{else}""#end#if( $foreach.hasNext ),#end #end }
- Click the tick next to the "Mapping template" dropdown.
- Click "<- Method Execution".
- Click "Deploy API".
- Deployment stage = "New stage", Stage name = "production".
- Click "Deploy".