Node.JS Wait for callback of REST Service that makes HTTP request

前端 未结 3 1801
故里飘歌
故里飘歌 2020-12-23 02:42

I am using express module to make a Restful API within Node.JS. In my service I am making additional http requests to outside Endpoints(server side) and I need to return the

相关标签:
3条回答
  • 2020-12-23 02:54

    A common practice is to use the async module.

    npm install async
    

    The async module has primitives to handle various forms of asynchronous events.

    In your case, the async#parallel call will allow you to make requests to all external APIs at the same time and then combine the results for return to you requester.

    Since you're making external http requests, you will probably find the request module helpful as well.

    npm install request
    

    Using request and async#parallel your route handler would look something like this...

    var request = require('request');
    var async = require('async');
    
    exports.handler = function(req, res) {
      async.parallel([
        /*
         * First external endpoint
         */
        function(callback) {
          var url = "http://external1.com/api/some_endpoint";
          request(url, function(err, response, body) {
            // JSON body
            if(err) { console.log(err); callback(true); return; }
            obj = JSON.parse(body);
            callback(false, obj);
          });
        },
        /*
         * Second external endpoint
         */
        function(callback) {
          var url = "http://external2.com/api/some_endpoint";
          request(url, function(err, response, body) {
            // JSON body
            if(err) { console.log(err); callback(true); return; }
            obj = JSON.parse(body);
            callback(false, obj);
          });
        },
      ],
      /*
       * Collate results
       */
      function(err, results) {
        if(err) { console.log(err); res.send(500,"Server Error"); return; }
        res.send({api1:results[0], api2:results[1]});
      }
      );
    };
    

    You can also read about other callback sequencing methods here.

    0 讨论(0)
  • 2020-12-23 02:55

    Wait.for https://github.com/luciotato/waitfor

    Other answer's examples using wait.for:

    Example from from Daniel's Answer (async), but using Wait.for

    var request = require('request');
    var wait = require('wait.for');
    
    exports.handler = function(req, res) {
    try {  
        //execute parallel, 2 endpoints, wait for results
        var result = wait.parallel.map(["http://external1.com/api/some_endpoint"
                     ,"http://external2.com/api/some_endpoint"]
                     , request.standardGetJSON); 
        //return result
        res.send(result);
    }
    catch(err){
        console.log(err); 
        res.end(500,"Server Error")
    }
    };
    
    //wait.for requires standard callbacks(err,data)
    //standardized request.get: 
    request.standardGetJSON = function ( options, callback) {
        request.get(options,
                function (error, response, body) {
                    //standardized callback
                    var data;
                    if (!error) data={ response: response, obj:JSON.parse(body)};
                    callback(error,data);
                });
    }
    
    0 讨论(0)
  • 2020-12-23 03:15

    Node.js is all about callbacks. Unless the API call is synchronous (rare and shouldn't be done) you never return values from those calls, but callback with the result from within the callback method, or call the express method res.send

    A great library for invoking web requests is request.js

    Let's take the really simple example of calling google. Using res.send, your express.js code could look like:

    var request = require('request');
    app.get('/callGoogle', function(req, res){
      request('http://www.google.com', function (error, response, body) {
        if (!error && response.statusCode == 200) {
          // from within the callback, write data to response, essentially returning it.
          res.send(body);
        }
      })
    });
    

    Alternatively, you can pass a callback to the method that invokes the web request, and invoke that callback from within that method:

    app.get('/callGoogle', function(req, res){
      invokeAndProcessGoogleResponse(function(err, result){
        if(err){
          res.send(500, { error: 'something blew up' });
        } else {
          res.send(result);
        }
      });
    });
    
    var invokeAndProcessGoogleResponse = function(callback){
      request('http://www.google.com', function (error, response, body) {
    
        if (!error && response.statusCode == 200) {
          status = "succeeded";
          callback(null, {status : status});
        } else {
          callback(error);
        }
      })
    }
    
    0 讨论(0)
提交回复
热议问题