context.getVariable() is not working to extract a query param using node.js in Apigee.

 
Solved Solved
0 1 1,348
1 ACCEPTED SOLUTION

You have several problems in that code.

  1. You cannot use context.getVariable() in a nodejs program. You can use context.getVariable() in a JavaScript callout, but not in a nodejs target. The two things use the same language (JavaScript) but they are not running in the same engine or context. The ambient objects like "context" and "properties" and "crypto" that exist in a JS callout environment, do not exist in a nodejs environment.
  2. You cannot use "let" in an Apigee Edge nodejs target. Apigee Edge supports node v0.10.32, which predates ES6.
  3. If you use a nodejs target, You need to structure the code so that it runs when a server request arrives. That means within the server listener function. here:
    var svr = http.createServer(function(req, resp) {
          // ...
          // your code to handle a request should be placed here...
          /// ...
          resp.end(data);
        });
    	

A restructuring might look something like this:

'use strict';
const fs = require('fs');
var http = require('http');
var url = require('url');


function requestHandler(request, response) {
  var queryData = url.parse(request.url, true).query;
  var reqParam = queryData.soaclassification
  var data=[],i;
  console.log("Reading applications.json");
  var rawdata = fs.readFileSync('applications.json', 'utf-8');
  var applications = JSON.parse(rawdata);
  var dataValue;
  var dataobject = {};


  // I'm not sure what's going on here....
  // It seems like we could accomplish this much more simply
  // with a filter and map, but I'm not clear.
  for(i = 0; i < applications.length; i++) {
    dataobject = applications[i];
    var dataobjectvalue = JSON.stringify(dataobject);
    dataValue = dataobject["soa-classification"];
    if(dataValue === reqParam) {
      if(i===0) {
        data = dataobjectvalue;
      }
      else {
        data = data +','+ dataobjectvalue;
      }
    }
  }

  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end(JSON.stringify(data));
}

console.log('node.js application starting...');
var svr = http.createServer(requestHandler);
svr.listen(9000, function() {
  console.log('Node HTTP server is listening');
});

If you can send me the applications.json file, or an example of same, and also send me what you expect to get as a response, I could implement the requestHandler so that it does what you're imagining.

Hang on, I checked your other post and got an example of the applications.json file.

See attached for a working API Proxy.

apiproxy-vidisha-1.zip

You can deploy this to your org+env and invoke it, like so:

curl -i https://ORG-ENV.apigee.net/vidisha-1?soaclassification=service%20provider

View solution in original post

1 REPLY 1

You have several problems in that code.

  1. You cannot use context.getVariable() in a nodejs program. You can use context.getVariable() in a JavaScript callout, but not in a nodejs target. The two things use the same language (JavaScript) but they are not running in the same engine or context. The ambient objects like "context" and "properties" and "crypto" that exist in a JS callout environment, do not exist in a nodejs environment.
  2. You cannot use "let" in an Apigee Edge nodejs target. Apigee Edge supports node v0.10.32, which predates ES6.
  3. If you use a nodejs target, You need to structure the code so that it runs when a server request arrives. That means within the server listener function. here:
    var svr = http.createServer(function(req, resp) {
          // ...
          // your code to handle a request should be placed here...
          /// ...
          resp.end(data);
        });
    	

A restructuring might look something like this:

'use strict';
const fs = require('fs');
var http = require('http');
var url = require('url');


function requestHandler(request, response) {
  var queryData = url.parse(request.url, true).query;
  var reqParam = queryData.soaclassification
  var data=[],i;
  console.log("Reading applications.json");
  var rawdata = fs.readFileSync('applications.json', 'utf-8');
  var applications = JSON.parse(rawdata);
  var dataValue;
  var dataobject = {};


  // I'm not sure what's going on here....
  // It seems like we could accomplish this much more simply
  // with a filter and map, but I'm not clear.
  for(i = 0; i < applications.length; i++) {
    dataobject = applications[i];
    var dataobjectvalue = JSON.stringify(dataobject);
    dataValue = dataobject["soa-classification"];
    if(dataValue === reqParam) {
      if(i===0) {
        data = dataobjectvalue;
      }
      else {
        data = data +','+ dataobjectvalue;
      }
    }
  }

  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end(JSON.stringify(data));
}

console.log('node.js application starting...');
var svr = http.createServer(requestHandler);
svr.listen(9000, function() {
  console.log('Node HTTP server is listening');
});

If you can send me the applications.json file, or an example of same, and also send me what you expect to get as a response, I could implement the requestHandler so that it does what you're imagining.

Hang on, I checked your other post and got an example of the applications.json file.

See attached for a working API Proxy.

apiproxy-vidisha-1.zip

You can deploy this to your org+env and invoke it, like so:

curl -i https://ORG-ENV.apigee.net/vidisha-1?soaclassification=service%20provider