2
votes

I am sending some form-data in request body from postman. In aws API Gateway I have set Content-type as "multipart/form-data" and mapping template is following:

    #set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"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
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #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",
    "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"
    }
}

However when I am getting the request on my lambda function everything is properly mapped into JSON, except my request body. Request body is coming as String. Following is the complete request:

  {
    "context": {
        "authorizer-principal-id": "",
        "cognito-authentication-type": "",
        "cognito-identity-id": "",
        "resource-path": "/env/Response",
        "account-id": "",
        "cognito-identity-pool-id": "",
        "request-id": "cd2052-11e7-92b6-e3c7d7dgh01",
        "api-id": "39dhjsr8",
        "resource-id": "skdsk5",
        "user-arn": "",
        "caller": "",
        "http-method": "POST",
        "cognito-authentication-provider": "",
        "api-key": "",
        "user": "",
    },
    "body-json": "------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"sig\"\r\n\r\nmcHeelgDQcYnjh5L2L92H8KLLE=\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"resultdescription\"\r\n\r\ncancelled.\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"result\"\r\n\r\nF\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"errorcode\"\r\n\r\n101\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"id\"\r\n\r\n420LU2UEG\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"key\"\r\n\r\ntdx\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"refid\"\r\n\r\n10480\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nTest\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"date\"\r\n\r\n2016-02-28T20:05:05.6330000Z\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx\r\nContent-Disposition: form-data; name=\"timestamp\"\r\n\r\n2016-02-29T04:15:47.4797Z\r\n------WebKitFormBoundaryLAn6jCAA10bF7ZMx--",
    "params": {
        "path": {},
        "querystring": {},
        "header": {
           },
    "stage-variables": {}
}

I have 2 queries regarding this:

  1. Is there any way where I can convert request body into JSON Object in API gateway mapping template itself?(Means instead of String, Request Body should come as JSON Object).
  2. Or I have to convert request body String into JSON Object at lambda handler in my java code?

Any help will be highly appreciated, as I am new to AWS.

2
This is one reason I try to avoid API Gateway Mapping templates. Using Lamda-Proxy integration is so much easier.Noel Llevares
Thanks but this I have read earlier and I am not getting any solution out of this.Pallavi Kaushik

2 Answers

2
votes

It would be best if you send your payload as application/json. That way, you can have it parsed in the mapping template using $util.parseJson() and the request body will come out as an object.

If you want to stick with form-data, you'll have to convert it inside your handler.

In Node.js, I use querystring module for this. Not sure what you can use in Java.

0
votes

You can use $util.parseJson() in body mapping template. It takes "stringified" JSON and returns an object representation of the result. You can use the result from this function to access and manipulate elements of the payload

Please read the documentation here