如何设计我的 Node.js API,以便我也可以从服务器端使用它?

Posted

技术标签:

【中文标题】如何设计我的 Node.js API,以便我也可以从服务器端使用它?【英文标题】:How do I design my Node.js API so that I can also consume it from the server side? 【发布时间】:2013-02-12 22:20:34 【问题描述】:

我有一个从 mongodb 返回一些 JSON 的 API:

// In router.js
var api = require('api') 
app.get('/lists', api.lists);

// In api.js
var db = require('db')
exports.lists = function(req, res) 
  db.lists.find(, function(err, lists) 
    res.send(lists);
  );
;

有没有办法设计 API,以便我也可以在我的 Node.js 应用程序中使用它?我试图避免在 API 之外复制任何数据库代码。我基本上有一个可以在服务器端呈现数据的控制器:

// In controller.js
var api = require('api')
exports.page = function(req, res) 
  res.send(api.lists()); // This won't work
;

我找到了一个 hacky 解决方案,即将回调函数传递给 api.lists(),但我觉得这是实现此目的的“错误”方式:

// In api.js
exports.lists = function(req, res, callback) 
  db.lists.find(, function(err, lists) 
    if(callback)
       callback(lists);
     else 
       res.send(lists);
    
  );
;

有什么想法吗?

【问题讨论】:

你想使用自己的api吗?以前从未听说过这个。也许您想使用可以在两个不同地方使用的模型...查看 express。 这听起来很像 wsdl/webservice 发现,即能够根据您公开的 api 调用自动创建方法/属性。如果是这样,祝你好运,到目前为止,我们已经尝试了一些标准化的尝试。 【参考方案1】:

我认为问题在于,在您当前的代码中,您将 API 耦合到响应对象。您可以通过以下方式将它们解耦:

在 router.js 中,不要使用 api.lists 作为回调,而是定义一个函数,该函数将调用 api.lists 并带有一个连接到响应对象的回调。在这种情况下, api.list 不需要知道响应对象,但我们正在创建的函数需要。

// In router.js
var api = require('api');
app.get('/lists', function(req, res) 
  api.lists(function(err, lists) 
    if(err) 
      res.send('error page');
      return;
    
    res.send(lists);
  );
);

在 api.js 中我们删除了对响应对象的引用。现在它将使用适当的数据(错误 + 列表)调用它收到的任何回调。由回调决定对结果做任何事情。

// In api.js
var db = require('db')
exports.lists = function(callback) 
  db.lists.find(, function(err, lists) 
    callback(err, lists);
  );
;

【讨论】:

以上是关于如何设计我的 Node.js API,以便我也可以从服务器端使用它?的主要内容,如果未能解决你的问题,请参考以下文章

如何保护简单的 Node.js RESTful API

如何在 openSUSE 上使用 NGINX 或 Apache2 将我的端口 80 重新路由到 localhost:3000 以便我可以运行我的 Node.js 应用程序

如何确保只有特定域可以从您的 REST api 查询?

Node.js:如何测试我的 API,模拟我的 API 调用的第三方 API

如何使用Backbone和Node.js / Hapi防止CORB错误?

使用Node.jsMongoDBFastify 构建API服务