Customizing http status code

Not applicable

Hello, I have invoked the lambda function using node.js.

My lambda function is:

import json
import requests
from requests.auth import HTTPBasicAuth
def my_handler(event, context):
    str1 = "{} {}~{} {}".format(event['start_date'],event['start_time'],event['end_date'],event['end_time'])
    str2 = "{}".format(event['unit'])
    mydict = {"select":"sum(message_count)","timeRange": str1,"timeUnit":str2}
    res = requests.get("https://api.enterprise.apigee.com/v1/o/organisation/environments/test/stats/response_status_code",mydict,auth=HTTPBasicAuth('xxx@gmail.com', 'xxxx'))
    response = {
        "statusCode": res.status_code,
        "body": json.loads(res.content)
    }
    r = json.dumps(response)
    loaded_r = json.loads(r)
    return loaded_r

My node.js is:

var util = require('util');
var AWS = require('aws-sdk');
var apigee = require('apigee-access');
var http = require('http');
var server = http.createServer(function (request, resp){
    
    AWS.config.accessKeyId="xxxxxxxxxxxxxxxxxxxx";
    AWS.config.secretAccessKey="xxxxxxxxxxxxxxxxxxxxxxxx";
    AWS.config.region ="ap-south-1";
    var lambda = new AWS.Lambda({region: 'ap-south-1', apiVersion: '2015-03-31'});
    var requestPayload = apigee.getVariable(request,'request.content');
    var params = {
        FunctionName: "analytics_api",
        InvocationType: 'RequestResponse',
        LogType:'Tail',
        Payload:requestPayload
    };
    console.log('Before lambda invoke function');
lambda.invoke(params,function(err, data) 
{
  if (err) 
  {
  console.log(err, err.stack); // an error occurred
  resp.end('Error:'+err);
  }
  else
  {
  console.log(data);           // successful response
  resp.end(data.Payload);
  }
});
});
server.listen(9001, function () {
    console.log('Node HTTP server is listening');
});

My output is:

{"body": {"environments": [{"dimensions": [{"metrics": [{"values": [{"timestamp": 1516665600000, "value": "27.0"}, {"timestamp": 1516579200000, "value": "21.0"}, {"timestamp": 1516492800000, "value": "2.0"}], "name": "sum(message_count)"}], "name": "200"}, {"metrics": [{"values": [{"timestamp": 1516665600000, "value": "6.0"}, {"timestamp": 1516579200000, "value": "23.0"}, {"timestamp": 1516492800000, "value": "0.0"}], "name": "sum(message_count)"}], "name": "401"}, {"metrics": [{"values": [{"timestamp": 1516665600000, "value": "6.0"}, {"timestamp": 1516579200000, "value": "0.0"}, {"timestamp": 1516492800000, "value": "0.0"}], "name": "sum(message_count)"}], "name": "404"}], "name": "test"}], "metaData": {"notices": ["Source:Postgres", "Table used: edge.api.faxgroupusenondn012.agg_target", "PG Host:ruappg0ro.apigeeks.net", "query served by:cb69b63c-ecad-49ad-a943-e4a37a1c9c1b"], "errors": []}}, "statusCode": 200}

I am getting my statuscode along with my response. I want to set that code to my http response code in the client side. I have tried java script file and Extract variables and all. But it shows, that variable is not found something like that. Please help me with the steps to be followed to achieve this. Where to include the policies like either in preflow or postflow, either in proxy endpoint or target endpoint like that.

Thanks in advance.

Solved Solved
2 3 3,415
1 ACCEPTED SOLUTION

Not applicable

I have set my response content to application/json in node.js as:

var server = http.createServer(function (request, response){
    
    response.setHeader('Content-Type', 'application/json');

//code....
}

I have added only JS Policy to my flow at response:

var c = JSON.parse(context.getVariable('response.content'));
context.setVariable('response.status.code', c.statusCode);

View solution in original post

3 REPLIES 3

@Preethi Ravichandran , Make sure you set response content type to application/json before you execute extract variables policy. You can extract response code from $.statusCode in extract variable policy attached to proxy or target endpoint response flow.

Hope it helps.

Preethi

I think this might work for you. I have a flow like this:

    <Flow name="flow1">
      <Request>
      </Request>
      <Response>
        <Step>
          <Name>AM-SetMockResponse</Name>
        </Step>
        <Step>
          <Name>JS-SetStatus</Name>
        </Step>
      </Response>
      <Condition>(proxy.pathsuffix MatchesPath "/t1") and (request.verb = "GET")</Condition>
    </Flow>

In the AM-SetMockResponse step, I use AssignMessage to set a response containing the payload you pasted above. In the JS-SetStatus step, I use a JavaScript step to extract the .statusCode property and set that into the context variable that Apigee Edge uses to set the response status code. The JS code looks like this:

var c = JSON.parse(context.getVariable('response.content'));
context.setVariable('response.status.code', c.statusCode);

This works. The response I get from the proxy reflects what is set in the JS Step. For example, if I modify your payload to be like this:

{
    "body": {
     ...
    },
    "statusCode": 203
}

...and then invoke the API Proxy with the above flow, I get this:

$ curl -i https://ORG-ENV.apigee.net/preethi-1/t1 
HTTP/1.1 203 Non-Authoritative Information
Date: Wed, 31 Jan 2018 01:18:22 GMT
Content-Type: application/json
Content-Length: 927
Connection: keep-alive


{"body": { ... }, "statusCode": 203}

See attached for a working example.

apiproxy-preethi-1.zip

Not applicable

I have set my response content to application/json in node.js as:

var server = http.createServer(function (request, response){
    
    response.setHeader('Content-Type', 'application/json');

//code....
}

I have added only JS Policy to my flow at response:

var c = JSON.parse(context.getVariable('response.content'));
context.setVariable('response.status.code', c.statusCode);