user414977
user414977

Reputation: 275

Multiple API requests with Node.js

I am trying to call multiple external api within for loop but as per the result i am getting only one iteration from the for loop sending the response back.

Yes, its not the right approach to handle multi api request, please suggest the best approach as it has to be sequential req/res

First Request - Call to find respective api. Response holds the data to feed into two api which are called within for-loop.

For-loop Second API Request - feeds data to the third API request.

var express = require('express');
var bodyParser = require('body-parser');
var Request = require("request");

var app = express();
app.use(bodyParser.json());

app.post('/building/', function (req, res) {
	'use strict';

	var myObject = null;

	var callSiteApi = {
		uri: 'http://localhost:8080/site/',
		body: JSON.stringify(req.body),
		method: 'POST',
		headers: {
			'Content-Type': 'application/json'
		}
	}
	// First External API Call
	Request(callSiteApi, function (error, response) {
		if (error) {
			console.log('ERROR with user request.');
			return response.sendStatus(500); // Return back that an error occurred
		} else {
			// Get data from response.body

    
			var materialquerystring = "mat="+response.body.material+"&date="+response.body.date;
            var floor = response.body.floor;

			for (var i = 0; i < floor.length; i++) {

				matereialValueURL = "http://localhost:8080/material/q="+materialquerystring;
				// Second External API Call within for loop
				Request.get(materialValueURL, (error, response, body) => {
					if (error) {
						console.log(req.error);
						
					}
					materialObject = JSON.parse(body);
          var valuequerystring = "value="+materialObject.value;
          // do somehting with materialObject
          
					console.log("first request iteration =" + i);

					sitevalueURL = "http://localhost:8080/value/q="+valuequerystring;
					// Third External API Call within for loop
					Request.get(sitevalueURL, (error, response, body) => {
						if (error) {
							logger.debug('[' + pid + '] ' + req.error);
							//return console.dir(error);
						}
						valueObject = JSON.parse(body);           
            console.log("second request iteration =" + i);
            // do somehting with valueObject 7 materialObject
            var a = materialObject.a;
            var b = valueObject.b;
            var c = a+b;
            
						
					});
				});
			}

			res.writeHead(200, {
				'Content-Type': 'application/json'
			});
			res.end('{"value-1":"a","value-2":"b","value-3":"c","material":"materialquerystring","value":"valuequerystring"}');
		}
	});
});

Upvotes: 0

Views: 1753

Answers (1)

Benny Powers
Benny Powers

Reputation: 5836

If you only need to get a number from the user's request, and then issue the same http request that number of times, something like this should do. I brought in a pointfree map helper from crocks to make things a little easier.

You might need to make a few adjustments here and there, particularly in the final then clause

const map = require('crocks/pointfree/map');

const app = express();

app.use(bodyParser.json());

const range = integer => [...new Array(integer).keys()]
const replicate = (i, x) => range(i).fill(x)

const handleError = error => {
  logger.debug(`['${pid}'] ${error.reponse.error}`)
  return error;
}

const getMaterialURIs = response =>
  replicate(response.body.floor.length, `http://localhost:8080/material/q=${response.body.material}`)

const processMaterialResponse = response => {
  doSomethingWithMaterial(response.body)
  return response;
}

const getSiteValueURI = response =>
  `http://localhost:8080/value/q=${response.body.value}`;

const processSiteValueResponse = response => {
  doSomethingWithSiteValue(response.body)
  return response;
}

app.post('/building/', function (req, res) {
  const uri = 'http://localhost:8080/site/';
  const body = JSON.stringify(req.body);
  const method = 'POST';
  const headers = { 'Content-Type': 'application/json' };

  // First External API Call
  Request({uri, body, method, headers})
    // 1: fetch to derive the material URI
    .then(getMaterialURIs)
    // 2: fetch from that material URI
    .then(map(Request.get))
    .then(Promise.all)
    // 3: process the material response
    .then(map(processMaterialResponse))
    // 4: derive the siteValueURI 
    .then(map(getSiteValueURI))
    // 5: fetch the siteValueURI
    .then(map(Request.get))
    .then(Promise.all)
    // 6: process the site value response
    .then(map(processSiteValueResponse))
    .catch(handleError)
    .then(response => {
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end('{"material":"materialquerystring","value":"valuequerystring"}');
    });
});

Upvotes: 2

Related Questions