这是在Express 4.0中进行API调用的最佳实践

时间:2016-09-29 09:30:42

标签: node.js rest express response

应用程序向服务器发出API请求并返回收到的响应。这里想了解

(i)是否正确地进行API调用并从服务器接收响应。

(ii)如果返回语句的返回语句是正确的

该模块被称为

str = apiRequest(search, lang);

模块是

var https = require('https');

function apiRequest(search, lang) {

   var options = {
       host: 'localhost:8080',
       path: '/api?search=' + search + '&lang=' + lang
   };


   function resData(res) {
       console.log("Status Code : ", res.statusCode);

       var str = '';

       res.on('data', function (chunk) {
           str += chunk;
       });

       res.on('end', function () {
           return JSON.parse(str);   // Is this a right way to return data
       });

       res.on('error', function(e) {
           console.error(e);
       });
   }

   https.get(options, resData).end();
};

1 个答案:

答案 0 :(得分:1)

不,这不起作用。我将对以下相关部分发表评论。

而不是apiRequest

function apiRequest(search, lang) {
   function resData(res) {
       // ...
       res.on('end', function () {
           return JSON.parse(str);   // Is this a right way to return data
       });
       // ...
   }
   https.get(options, resData).end();
}

并用:

调用它
str = apiRequest(search, lang);

您应该通过回调或返回承诺

使用回调

您的apiRequest函数可以采取额外的参数,即回调:

function apiRequest(search, lang, callback) {
   function resData(res) {
       // ...
       res.on('end', function () {
           callback(null, JSON.parse(str));
       });
       res.on('error', function(e) {
           console.error(e);
           callback(e);
       });
       // ...
   }
   https.get(options, resData).end();
}

现在您可以将其用作:

apiRequest(search, lang, function (error, str) {
    if (err) {
        // you have error
    } else {
        // you have your str here
    }
});

使用承诺

您的apiRequest函数可以返回一个承诺:

function apiRequest(search, lang, callback) {
   return new Promise(function (resolve, reject) {
     function resData(res) {
       // ...
       res.on('end', function () {
           resolve(JSON.parse(str));
       });
       res.on('error', function(e) {
           console.error(e);
           reject(e);
       });
       // ...
     }
     https.get(options, resData).end();
   }
}

现在您可以将其用作:

apiRequest(search, lang)
.then(function (str) {
    // you have your str here
})
.catch(function (err) {
    // you have error
});

这未经过测试,因此可能存在一些小错误,但这是一般性的想法。当我发现一些错误时,我会更新答案。

摘要

总而言之,您可以使用两种样式来组合这样的异步函数:回调或承诺。您将无法仅返回数据,因为return基本上是同步的 - 您必须立即返回 - 除非您返回的是可以在以后解决或拒绝的承诺。

解析JSON

还应记住,您应始终在JSON.parse()内运行try {} catch {} block来处理错误的JSON错误,否则整个应用程序可能会崩溃。 JSON.parse()会在输入错误时抛出异常。有关详细信息,请参阅this answer

这会使您的代码更加复杂,但您可以使用request模块避免这种复杂化并使其更简单 - 请参阅下面的更新。

更简单的例子

回调

要有一个更简单的工作示例,并且您不必手动解析JSON,请考虑我刚刚编写的代码,基于您的示例,但调用GitHub API,以便每个人都可以测试它 - 它给出他的GitHub昵称打印某人的网站,但其他方式与你的代码类似:

'use strict';
var request = require('request');

function apiRequest(search, callback) {

  var options = {
    url: 'https://api.github.com/users/' + search,
    json: true,
    headers: {'User-Agent': 'request'}
  };

  function resData(err, res, data) {
    if (err) {
      callback(err);
    } else if (res.statusCode !== 200) {
      callback(res.statusCode);
    } else {
      // data is already parsed as JSON:
      callback(null, data.blog);
    }
  }

  request.get(options, resData);

}

apiRequest('rsp', function (err, data) {
  if (err) {
    console.log('Error:', err);
  } else {
    console.log('Data:', data);
  }
});

这是使用回调的示例。

承诺

以下是使用promises的示例:

'use strict';
var request = require('request');

function apiRequest(search, callback) {

  return new Promise(function (resolve, reject) {

    var options = {
      url: 'https://api.github.com/users/' + search,
      json: true,
      headers: {'User-Agent': 'request'}
    };

    function resData(err, res, data) {
      if (err) {
        reject(err);
      } else if (res.statusCode !== 200) {
        reject(res.statusCode);
      } else {
        // data is already parsed as JSON:
        resolve(data.blog);
      }
    }

    request.get(options, resData);

  });

}

apiRequest('rsp')
  .then(function (data) {
    console.log('Data:', data);
  })
  .catch(function (err) {
    console.log('Error:', err);
  });

简化

使用胖箭头函数和匿名函数以及对象文字可以进一步简化它:

'use strict';
var request = require('request');

function apiRequest(search, callback) {

  return new Promise((resolve, reject) => {
    request.get({
      url: 'https://api.github.com/users/' + search,
      json: true,
      headers: {'User-Agent': 'request'}
    }, (err, res, data) => {
      if (err) {
        reject(err);
      } else if (res.statusCode !== 200) {
        reject(res.statusCode);
      } else {
        resolve(data.blog);
      }
    });
  });

}

apiRequest('rsp')
  .then(data => console.log('Data:', data))
  .catch(err => console.log('Error:', err));

更多信息

您可以看到其他一些答案,其中我解释了回调和承诺之间的区别以及如何更详细地使用它们,您可能会觉得有用: