Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API gateway return XML

I have a lambda function which returns an string(xml to string) to the API gateway. Now the API gateway returns the string but it is not an valid XML. I already set the content type to application/xml.

The XML looks like this:

"<TEST xmlns:ns0=\"https://www.w3.org/2001/XMLSchema-instance\" version=\"3.0\" >\n  <InLine>\n  <tag1>valuetag1</tag1>\n</InLine>\n   \n</TEST>"

How can I fix this?

like image 745
Polle Avatar asked Jun 11 '17 15:06

Polle


4 Answers

The forum thread is useful. Also watch out that the string you have pasted is not valid XML even if you manage to return it with mapping.

Anyhow I had a similar problem and this is how I solved it (very similar to the forum link discussions above).

  1. Make sure your Lambda returns something which can be converted to XML. If your lambda is in python, your handler could be something like this:

def lambda_handler(event, context): resp = {"body" : "<FooResult xmlns='http://someorg.com/xml/1.0'><Message>All is well</Message></FooResult>"} return resp

Note that I have wrapped the actual response XML string in json. The key for this json element is "body". And the value for that key is a valid XML string inside double quotes.

  1. Now add a response body mapping template in the Integration Response for your API in the API Gateway. This should be the content of the template:

#set($inputRoot = $input.path('$')) $inputRoot.body

This template will return the valid XML value in the key "body" in your JSON.

Now you just have to add a Content-Type header and response body of application/xml in the Method Response section, and you should be getting valid XML.

Remember to set the accept header on your client to accept XML. Cheers

like image 71
Sundar Avatar answered Oct 18 '22 15:10

Sundar


By default API Gateway and Lambda expect JSON data. It is definitely possible to return XML data, but depending on how you've configured your Lambda integration, it will require different configuration.

The forum thread mentioned in comments will apply if you are using the standard Lambda integration with mapping templates. If you are using the Lambda Proxy integration you will need to escape your XML and embed it inside of the returned JSON payload as defined in the documentation.

like image 24
Bob Kinney Avatar answered Oct 18 '22 14:10

Bob Kinney


make sure you set the 'Content-Type' in the response like below in your lambda function

... let response = { statusCode: 200, headers: { 'Content-Type': 'text/xml' }, body: YOUR_XML_STRING }; callback(null, response); ...

like image 45
vedat Avatar answered Oct 18 '22 16:10

vedat


When returning a JSON object from AWS Lambda to API Gateway, send a 'Content-Type': 'text/xml' header and the XML string in the body.

exports.handler = async function (event) {
    const response = {
        statusCode: 200,
        headers: { 'Content-Type': 'text/xml' },
        body: "<?xml version="1.0" encoding="UTF-8"?><Response><Message>Hello</Message></Response>"
    };

    return response;
};

If you are new to Lambda, the docs code examples don't address this XML but notably show important details on how the function parameters, return, and possible callback should be structured for async vs sync, promises, etc.

like image 29
David Avatar answered Oct 18 '22 14:10

David