19
votes

With Azure Functions, what do you need to do to return a JSON object in the body from a function written in node.js? I can easily return a string, but when I try to return a json object as shown below I appear to have nothing returned.

context.res = {
   body: jsonData,
   contentType: 'application/json'
};
6
Also note that to specify the content type of the response, you do that via the headers collection on the response, e.g. context.res.headers = { 'Content-Type': 'text/plain' }. As David says below, we'll default that to application/json for you if your response is json. - mathewc

6 Answers

35
votes

Based on my recent testing (March 2017). You have to explicitly add content type to response headers to get json back otherwise data shows-up as XML in browser.

"Content-Type":"application/json"

res = {
    status: 200, /* Defaults to 200 */
    body: {message: "Hello " + (req.query.name || req.body.name)},
    headers: {
        'Content-Type': 'application/json'
    }
};

Full Sample below:

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    context.log(context);

    if (req.query.name || (req.body && req.body.name)) {
        res = {
            // status: 200, /* Defaults to 200 */
            body: {message: "Hello " + (req.query.name || req.body.name)},
            headers: {
                'Content-Type': 'application/json'
            }
        };
    }
    else {
        res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
    context.done(null, res);
};
12
votes

If your data is a JS object, then this should just work, e.g.

module.exports = function(context, req) {
    context.res = {
        body: { name: "Azure Functions" }
    };
    context.done();
};

This will return an application/json response.

If instead you have your data in a json string, you can have:

module.exports = function(context, req) {
    context.res = {
        body: '{ "name": "Azure Functions" }'
    };

    context.done();
};

Which will return an application/json response because it sniffs that it is valid json.

1
votes

I would like to add one more point. Apart from making the body: a JSON object, the request should also contain proper headers telling server what content type we are interested in. I could see that same Azure function when just invoked via browser using URL gives XML response, but when invoking from script or tools like Postman it gives JSON.

1
votes

I feel like the answer has been given but it hasn't been clearly presented so I thought I'd answer as well in case it will help anyone coming behind me. I too have created a function that most definitely returns a Javascript object but if I copy and paste the URL in the Azure Function UI and just open a new tab in Chrome and try to view the output, I actually get back an XML document that tells me there's an error (not surprising there's an error as many characters in the Javascript would have blown up the XML). So, as others have mentioned, the key is sending the appropriate headers with your request. When you copy/paste the URL into your browser, the browser is sending a request header that looks similar to this:

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8

When that happens, you see the XML return as described in this link: https://github.com/strongloop/strong-remoting/issues/118

In order to get around this problem and see what the data would look like with a JSON request, either use a utility like Postman: https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en

Accept: application/json

Sample Postman Header Settings

Or use a CURL command and pass in the proper Accept header.

As you can see in the screenshot above, when I provided the proper header, I get back the JSON response I would expect.

1
votes
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');

if (req.query.name || (req.body && req.body.name)) {
    context.res = {
        // status: 200, /* Defaults to 200 */
        body: {"data":"Hello"},
        headers: {
            'Content-Type': 'application/json'
        }
    };
}
else {
    // res = {
    //     status: 400,
    //     body: "Please pass a name on the query string or in the request body"
    // };
}
context.done(null,res);
0
votes

You can also use JSON.stringify() to make a valid json string out of your js-object:

jsonData = { value: "test" }:

context.res = {
   body: JSON.stringify(jsonData)
};