my goal is to get a list of files from a google drive folder and its subfolders as json string. so i can then use express to expose it as an API endpoint that other applications can connect to it.
the code is working. i get everything i want, but i do not know how to export my data variable to app.js
// get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
data
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data = JSON.stringify({ title : resp.title, description : resp.description, url : url});
//console.log(data);
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function() { return data; };
and in my app.js i use this
// app.js
var jsonData = require('./get-filelist');
console.log('output: ' + jsonData.files());
the data variable in app.js doesnt contain any data, while checking the output inside the function getFilesInfo() is working.
so, how to make my data variable accessible in other scripts?
You've got a problem with sync/async behavior.
app.js should be aware when to call the files() function exported from get-filelist. The code you've got there calls the files() function immediately after requiring the get-filelist module. At that moment the data variable is still empty.
Best solution would be to provide the files() function with a callback that will trigger once you've loaded the data variable.
Of course, you will need some extras:
the loaded flag so that you know whether to trigger the callback immediately (if data is already loaded) or postpone the trigger once the load is done.
the array for waiting callbacks that will be triggered upon load (callbacks).
// get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
loaded = false, //loaded? Initially false
callbacks = [], //callbacks waiting for load to finish
data = [];
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
data = []; //data is actually an array
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data.push(JSON.stringify({ title : resp.title, description : resp.description, url : url}));
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
//console.log(data); //now, that the array is full
//loaded is true
loaded = true;
//trigger all the waiting callbacks
while(callbacks.length){
callbacks.shift()(data);
}
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function(callback) {
if(loaded){
callback(data);
return;
}
callbacks.push(callback);
};
Now the app.js behavior needs to change:
// app.js
var jsonData = require('./get-filelist');
jsonData.files(function(data){
console.log('output: ' + data);
});
/* a much more elegant way:
jsonData.files(console.log.bind(console,'output:'));
//which is actually equivalent to
jsonData.files(function(data){
console.log('output: ',data); //without the string concatenation
});
*/
Related
I am pretty new to back end programming with JavaScript and have written some code to query a database and return the results as JSON. It seems to be working correctly in the browser, but my iOS code isn't getting any data from it. I have it running locally for now while testing. If you look in my Swift that gets the data from the URL, I'm getting the NO JSON from the print statement in the catch.
JavaScript
'use strict';
var util = require('util');
var sql = require("mssql");
var express = require('express');
var port = process.env.PORT || 1337;
var membershipNumber;
var queryString;
var app = express();
app.get('/membership/:number', function (req, res) {
console.log("\nPARAMS:");
console.log(req.params.number);
membershipNumber = req.params.number;
queryString = util.format('SELECT major_key, company, status, paid_thru FROM name WHERE major_key = \'%s\' and member_record = 1', membershipNumber);
console.log("\nQUERY:");
console.log(queryString);
res.setHeader('Content-Type', 'application/json');
res.set('Content-Type', 'application/json');
membershipStatusQuery(queryString, res);
});
app.get('/', function (req, res) {
var dictionary = [];
dictionary.push({
key: "none"
});
var jsonDict = JSON.stringify(dictionary);
res.setHeader('Content-Type', 'application/json');
res.set('Content-Type', 'application/json');
res.send(jsonDict);
});
function membershipStatusQuery(query, response) {
var config = {
server: 'DB_Server',
database: 'testDB',
user: 'sa',
password: 'password',
port: 1433
};
var connection = new sql.Connection(config);
connection.connect().then(function () {
var req = new sql.Request(connection);
req.query(query).then(function (recordset) {
connection.close();
response.send(results);
})
.catch(function (err) {
console.log(err);
connection.close();
response.send(err);
});
})
.catch(function (err) {
console.log(err);
response.send(err);
});
}
app.listen(port, function () {
console.log("Listening on port %s", port);
});
RESULTS
[{"major_key":"0001354648","company":"Membership of David Metzgar","status":"A","paid_thru":"2017-10-31T00:00:00.000Z"}]
iOS Swift Code
Class to get JSON from URL:
import UIKit
class GetJSON: NSObject {
func getJSONFrom(urlString: String) -> JSON {
let url = URL(string: urlString)
var data = Data()
do {
data = try Data(contentsOf: url!)
} catch {
print("No JSON")
// TODO: Display error
}
let json = JSON(data: data)
return json
}
}
Method from another class to use JSON:
func getQueryResultsJSON() {
print("http://localhost:1337/membership/\(memberNumberTextField.text!)")
// let jsonURL = "http://localhost:1337/membership/\(memberNumberTextField.text!)"
let jsonURL = "http://localhost:1337/membership/0001354648"
let getJSON = GetJSON()
self.resultsArray = getJSON.getJSONFrom(urlString: jsonURL)
if let dictionary = resultsArray?[0].dictionaryObject {
if let status = dictionary["status"] {
if status as! String == "A" {
print(dictionary)
print("Provided membership is active")
// membership is active
// TODO: save info and display membership card
} else {
print(dictionary)
print("Provided membership is NOT active")
// membership is not active
// TODO: display alert
}
} else {
print("DOESN'T EXIST!")
// membership number does not exist
// TODO: display alert
}
} else {
print("NOTHING!")
}
}
let url = NSURL(string: "your url")!
let request = NSMutableURLRequest(url: url as URL)
// request.httpMethod = "POST"
// request.httpBody = jsonData
//request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request as URLRequest){ data,response,error in
if error != nil {
return
}
do {
let userObject = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: String]
if userObject != nil {
// do something
}
} catch let jsonError {
print(jsonError)
print(String(data: data!, encoding: String.Encoding.utf8)!)
}
}
task.resume()
I am trying to create an API using a local server for testing. The route
'GET' works fine, however 'POST' has a problem and it is returning 'Cannot GET /add/name'. I am developing the API using node.js and Express. Why am I receiving get when the route is set to 'POST'? Where is the problem?
var fs = require('fs');
var data = fs.readFileSync('events.json');
var allEvents = JSON.parse(data);
console.log(allEvents);
console.log('Server running.');
var express = require('express');
var app = express();
var sever = app.listen(3000, listening);
function listening() {
console.log('Serving...');
}
app.use(express.static('website'));
//GET and send all data from JSON
app.get('/all', sendAll);
function sendAll(request, response) {
response.send(allEvents);
}
//POST new data to JSON
app.post('/add/:name', addData);
function addData(request, response) {
var newData = request.params;
var name = newData.name;
var eventType = newData.eventType;
var reply;
// var newEvent = {
// name: ":name",
// eventType: ":eventType",
// };
var newData = JSON.stringify(allEvents, null, 2);
fs.writeFile('events.json', newData, finished);
function finished(err) {
console.log('Writting');
console.log(err);
var reply = {
word: word,
score: score,
status: 'Success'
}
response.send(reply);
}
}
Request
$(function() {
//HTML
var $list = $('#list');
var jsonURL = '../events.json'
$.ajax({
type: 'GET',
url: '/all',
success: function(data) {
console.log('Data received', data);
$.each(data, function (type, string) {
$list.append('<li>' + type + " : " + string + '</li>');
});
},
error: function (err) {
console.log('Error, data not sent.', err);
}
});
$('#submit').on('click', function () {
// var newEvent = {
// name: $name.val(),
// eventType: $eventType.val(),
// };
var name = $('#fieldName').val();
var eventType = $('#fieldEventType').val();
console.log(name);
$.ajax({
type: 'PUT',
url: '/add/' + name,
success: function (addData) {
$list.append('<li>name: ' + name + '</li>');
},
error: function (err) {
console.log('Error saving order', err);
}
});
});
});
Thank you in advance.
For testing POST request, you can use Postman to test it. If you use the browser to call the api, it will be GET method instead of POST.
I'm using the codebird library to perform some requests to the Twitter API. These requests respond correctly but I want to pass that response through to my route. Here is a snippet of my route.js:
router.get('/twitter', function(req, res) {
twitterAPI.callAPI(function(tweetData) {
console.log('callback for twitterCall');
res.send(tweetData);
});
});
This is my code from module1.js:
require('es6-promise').polyfill();
require('isomorphic-fetch');
var Codebird = require("codebird");
// using twitter-aggregation app for consumer key and secret
var params = {
screen_name: 'kanyewest'
};
var config = {
twitter : {
consumerKey: 'thisismykey',
consumerSecret: 'thisismysecret'
}
};
var cb = new Codebird;
cb.setConsumerKey(config.twitter.consumerKey, config.twitter.consumerSecret);
var tweetData = {};
// Function to call twitter api, called by route
var callAPI = function(callback) {
getAccessToken(callback());
console.log('callAPI function loaded');
};
var getAccessToken = function(callback) {
cb.__call(
"oauth2_token",
{},
function (reply, err) {
var accessToken;
console.log('1. response received');
if (err) {
console.log("error response or timeout exceeded" + err.error);
return;
}
if (reply) {
console.log('2. twitter: reply received');
console.log(reply);
accessToken = reply.access_token;
getUserTweets(accessToken, callback);
}
}
);
};
var getUserTweets = function(authToken, callback) {
console.log('passed accessToken');
console.log(authToken);
console.log(typeof callback);
cb.__call(
"users_show",
params,
function (reply, rate, err) {
if (err) {
console.log("Error in showing user or timed out" + err.error);
}
if (reply) {
console.log("received user's tweet");
var newTweetData = {
screen_name: reply.screen_name,
name: reply.name,
status_text: reply.status.text,
status_date: reply.status.created_at,
status_retweets: reply.status.retweet_count,
status_favourites: reply.status.favorite_count
};
console.log(newTweetData);
// final callback to set a variable
console.log(typeof callback);
setTweetData(newTweetData, callback);
// console.log('getUserTweets callback');
// callback;
}
}
);
};
var setTweetData = function(newTweetData, callback) {
if(!newTweetData) {
return 'variable is a string, not function';
}
tweetData = newTweetData;
console.log('tweet data has been set');
console.log(callback);
callback(tweetData);
};
module.exports = { params, callAPI };
Not sure what the proper way is to pass that callback from my route, through to the end of my function chain so that my res.send() triggers once I have acquired the twitter data.
You have to change callApi method to pass "callback" as parameter and not call it.
var callAPI = function(callback) {
getAccessToken(callback);
// and not getAccessToken(callback());
console.log('callAPI function loaded');
};
The difference is, in you code you are calling the callback just after authentication.
After my change, you pass the callback to getUserTweets function, and it will call the callback after tweets fetched.
I am using azure mobile services, with following custom API:
var returnVal = new Object;
exports.post = function (request, response) {
// Use "request.service" to access features of your mobile service, e.g.:
// var tables = request.service.tables;
// var push = request.service.push;
var merchantdetailsTable = request.service.tables.getTable("merchantdetails");
var resourceName;
//console.log(JSON.stringify(request.parameters));
merchantdetailsTable.insert({
name: request.body.workerNameInput,
emailid: request.body.workerEmailIDInput,
contact: request.body.workerContactNumberInput
}).then(function (merchantInserted) {
returnVal.workerId = merchantInserted.id;
resourceName = returnVal.workerId.toLowerCase();
var shopworkersTable = request.service.tables.getTable("shopworkers");
return shopworkersTable.insert({
id: merchantInserted.id,
shopid: request.body.shopId
});
}, function(err){
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).then(function () {
var accountName = appSettings.STORAGE_ACCOUNT_NAME;
var accountKey = appSettings.STORAGE_ACCOUNT_ACCESS_KEY;
var host = accountName + '.blob.core.windows.net';
var blobService = azure.createBlobService(accountName, accountKey, host);
return blobService.createContainerIfNotExists("merchant-image", { publicAccessLevel: 'blob' });
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).then(function(error){
if (!error) {
// Provide write access to the container for the next 5 mins.
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Expiry: new Date(new Date().getTime() + 5 * 60 * 1000)
}
};
// Generate the upload URL with SAS for the new image.
var sasQueryUrl =
blobService.generateSharedAccessSignature("merchant-image",
'', sharedAccessPolicy);
// Set the query string.
returnVal["merchantImage"].sasQueryString = qs.stringify(sasQueryUrl.queryString);
// Set the full path on the new new item,
// which is used for data binding on the client.
returnVal["merchantImage"].imageUri = sasQueryUrl.baseUrl + sasQueryUrl.path + '/'
+ resourceName;
var accountName = appSettings.STORAGE_ACCOUNT_NAME;
var accountKey = appSettings.STORAGE_ACCOUNT_ACCESS_KEY;
var host = accountName + '.blob.core.windows.net';
var blobService = azure.createBlobService(accountName, accountKey, host);
return blobService.createContainerIfNotExists("pharmacy-certificate", { publicAccessLevel: 'blob' });
}
else {
return response.send(statusCodes.INTERNAL_SERVER_ERROR);
}
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
}).done(function (error) {
if (!error) {
// Provide write access to the container for the next 5 mins.
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.Constants.BlobConstants.SharedAccessPermissions.WRITE,
Expiry: new Date(new Date().getTime() + 5 * 60 * 1000)
}
};
// Generate the upload URL with SAS for the new image.
var sasQueryUrl =
blobService.generateSharedAccessSignature("pharmacy-certificate",
'', sharedAccessPolicy);
// Set the query string.
returnVal["pharmacyCertificate"].sasQueryString = qs.stringify(sasQueryUrl.queryString);
// Set the full path on the new new item,
// which is used for data binding on the client.
returnVal["pharmacyCertificate"].imageUri = sasQueryUrl.baseUrl + sasQueryUrl.path + '/'
+ resourceName;
response.send(statusCodes.OK, returnVal);
}
else {
return response.send(statusCodes.INTERNAL_SERVER_ERROR);
}
}, function (err) {
return response.send(statusCodes.INTERNAL_SERVER_ERROR, err);
});
response.send(statusCodes.OK, { message : 'Hello World!' });
};
exports.get = function(request, response) {
response.send(statusCodes.OK, { message : 'Hello World!' });
};
I am getting following error:
TypeError: Cannot call method 'then' of undefined
at exports.post (D:\home\site\wwwroot\App_Data\config\scripts\api\addWorker.js:17:8)
Azure Mobile Services does not return promises from table operations. You need to pass an options object that contains success and error callbacks, as described at https://msdn.microsoft.com/en-us/library/azure/jj554210.aspx.
I highly recommend that you take a look at the newer implementation of the product, Azure Mobile Apps - https://www.npmjs.com/package/azure-mobile-apps. (Disclaimer: I work for Microsoft on the Azure Mobile Apps team)
Is it sensible to use Node.js to write a stand alone app that will connect two REST API's?
One end will be a POS - Point of sale - system
The other will be a hosted eCommerce platform
There will be a minimal interface for configuration of the service. nothing more.
Yes, Node.js is perfectly suited to making calls to external APIs. Just like everything in Node, however, the functions for making these calls are based around events, which means doing things like buffering response data as opposed to receiving a single completed response.
For example:
// get walking directions from central park to the empire state building
var http = require("http");
url = "http://maps.googleapis.com/maps/api/directions/json?origin=Central Park&destination=Empire State Building&sensor=false&mode=walking";
// get is a simple wrapper for request()
// which sets the http method to GET
var request = http.get(url, function (response) {
// data is streamed in chunks from the server
// so we have to handle the "data" event
var buffer = "",
data,
route;
response.on("data", function (chunk) {
buffer += chunk;
});
response.on("end", function (err) {
// finished transferring data
// dump the raw data
console.log(buffer);
console.log("\n");
data = JSON.parse(buffer);
route = data.routes[0];
// extract the distance and time
console.log("Walking Distance: " + route.legs[0].distance.text);
console.log("Time: " + route.legs[0].duration.text);
});
});
It may make sense to find a simple wrapper library (or write your own) if you are going to be making a lot of these calls.
Sure. The node.js API contains methods to make HTTP requests:
http.request
http.get
I assume the app you're writing is a web app. You might want to use a framework like Express to remove some of the grunt work (see also this question on node.js web frameworks).
/*Below logics covered in below sample GET API
-DB connection created in class
-common function to execute the query
-logging through bunyan library*/
const { APIResponse} = require('./../commonFun/utils');
const createlog = require('./../lib/createlog');
var obj = new DB();
//Test API
routes.get('/testapi', (req, res) => {
res.status(201).json({ message: 'API microservices test' });
});
dbObj = new DB();
routes.get('/getStore', (req, res) => {
try {
//create DB instance
const store_id = req.body.storeID;
const promiseReturnwithResult = selectQueryData('tablename', whereField, dbObj.conn);
(promiseReturnwithResult).then((result) => {
APIResponse(200, 'Data fetched successfully', result).then((result) => {
res.send(result);
});
}).catch((err) => { console.log(err); throw err; })
} catch (err) {
console.log('Exception caught in getuser API', err);
const e = new Error();
if (err.errors && err.errors.length > 0) {
e.Error = 'Exception caught in getuser API';
e.message = err.errors[0].message;
e.code = 500;
res.status(404).send(APIResponse(e.code, e.message, e.Error));
createlog.writeErrorInLog(err);
}
}
});
//create connection
"use strict"
const mysql = require("mysql");
class DB {
constructor() {
this.conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'db_name'
});
}
connect() {
this.conn.connect(function (err) {
if (err) {
console.error("error connecting: " + err.stack);
return;
}
console.log("connected to DBB");
});
}
//End class
}
module.exports = DB
//queryTransaction.js File
selectQueryData= (table,where,db_conn)=>{
return new Promise(function(resolve,reject){
try{
db_conn.query(`SELECT * FROM ${table} WHERE id = ${where}`,function(err,result){
if(err){
reject(err);
}else{
resolve(result);
}
});
}catch(err){
console.log(err);
}
});
}
module.exports= {selectQueryData};
//utils.js file
APIResponse = async (status, msg, data = '',error=null) => {
try {
if (status) {
return { statusCode: status, message: msg, PayLoad: data,error:error }
}
} catch (err) {
console.log('Exception caught in getuser API', err);
}
}
module.exports={
logsSetting: {
name: "USER-API",
streams: [
{
level: 'error',
path: '' // log ERROR and above to a file
}
],
},APIResponse
}
//createlogs.js File
var bunyan = require('bunyan');
const dateFormat = require('dateformat');
const {logsSetting} = require('./../commonFun/utils');
module.exports.writeErrorInLog = (customError) => {
let logConfig = {...logsSetting};
console.log('reached in writeErrorInLog',customError)
const currentDate = dateFormat(new Date(), 'yyyy-mm-dd');
const path = logConfig.streams[0].path = `${__dirname}/../log/${currentDate}error.log`;
const log = bunyan.createLogger(logConfig);
log.error(customError);
}
A more easy and useful tool is just using an API like Unirest; URest is a package in NPM that is just too easy to use jus like
app.get('/any-route', function(req, res){
unirest.get("https://rest.url.to.consume/param1/paramN")
.header("Any-Key", "XXXXXXXXXXXXXXXXXX")
.header("Accept", "text/plain")
.end(function (result) {
res.render('name-of-the-page-according-to-your-engine', {
layout: 'some-layout-if-you-want',
markup: result.body.any-property,
});
});