Javascript Node.js API设计和路由处理

Javascript Node.js API设计和路由处理,javascript,node.js,api-design,Javascript,Node.js,Api Design,我真的不知道该给它取什么名字,但我对Node.js是新手。我刚刚在GitHub上找到一个整洁的RESTAPI项目来实现,但我不确定如何将所有GET和POST等拆分为单独的文件 我有一个单数的api.js文件 function API_ROUTER(router, connection, md5) { var self = this; self.handleRoutes(router, connection, md5); } API_ROUTER.prototype.handle

我真的不知道该给它取什么名字,但我对
Node.js
是新手。我刚刚在GitHub上找到一个整洁的RESTAPI项目来实现,但我不确定如何将所有GET和POST等拆分为单独的文件

我有一个单数的
api.js
文件

function API_ROUTER(router, connection, md5) {
    var self = this;
    self.handleRoutes(router, connection, md5);
}

API_ROUTER.prototype.handleRoutes = function(router, connection, md5) {
    router.get("/", function(req, res) {
        res.json({"Message" : "Hello World !"});
    });
};

module.exports = API_ROUTER;
现在,我如何创建兄弟姐妹
other.js
并使用:

var api = require('./api.js');

// Create router.get, router.post etc. here?
但我不确定如何将所有GET和POST等拆分为单独的文件

组织路由的一种方法是为每个路由使用一个单独的对象,该对象包含处理程序(由HTTP方法分隔)和其他所需信息,例如路径:

api/home.js

module.exports =  {
   path: '/',
   handlers: {
     'get': function(req, res) {
          res.json({"Message" : "Hello World !"});
      },
      'post': { 
        // ...
      }
      // ...
    }
}
api/other.js

module.exports =  {
   path: '/other',
   handlers: {
     'get': function(req, res) {
        res.json({"Message" : "Other !"});
      },
    // ...
然后,您可以在
HandlerRoutes
方法中加载所有这些:

API_ROUTER.prototype.handleRoutes = function(router, connection, md5) {
   var routes = ['home', 'other'];

   routes.forEach(function(name) {
     // load the current route object (NOTE: you should use the path module for determining file path in a cross-platform manner)
     var routeObject = require('./' + name + '.js');

     var apiPath = routeObject.path;
     var handlers = routeObject.handlers;
     var methods = Object.keys(handlers);

     // assign handlers for each method
     methods.forEach(function(method) {
       router[method](apiPath, handlers[method]);
     });

   });
};
这将使用适当的信息和处理程序安装所有路由。 现在,您可以通过使用必要的数据实例化
API\u路由器来调用此代码:

// initialize the api (and handle the routes internally)
var Api = new require('./api.js')(router, connection, md5);

如果您实现了RESTful API,那么您应该记住,这只是提供数据的一种方式,您可能希望在将来对其进行更改,因为API在大多数情况下只是一个转换层

通常,您会根据资源分割代码,处理请求的代码不会有太多逻辑,它只会接受请求并将其传递给内部API。为此,如果您已经使用了
express.js
或类似的库,那么实际上不需要额外的层

在express中,已经提供了模块化代码所需的功能。对于每个资源,您将创建一个自己的
express.Router
,它本身也可能装载另一个子模块。因此,对于这一部分,您并不真正需要一个库

图书馆什么时候有用:

  • 如果它自动将抛出的错误转换为正确的响应代码
  • 如果它包括一个自动创建API文档的工具
  • 如果它完全抽象了基线布线系统,以便您可以连接到
    express
    hapi
    。。。无需更改代码
下面是使用
express.js
的安装程序的外观

/lib/rest/customer.js

var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();

router.get('/:id', function(req, res, next) {
  customerSystem.find({
    id: req.params.id
  }, function(err, customer) {
    if (err) {
      res.status( /*correct status code*/ ).send( /*depending on the api return json, xml, ....*/ )
    } else {
      res.send( /*depending on the api return json, xml, ....*/ )
    }
  })
});

router.delete('/:id', function(req, res, next) {
  customerSystem.delete({
    id: req.params.id
  }, function(err) {
    //...
  });
});


router.post('/', function(req, res, next) {
  //...
});

//save the customer id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
  req.customerId = req.params.id;
  next();
});

router.use('/:id/addresses', require('./customer-address') )

module.exports = router;
var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();

router.get('/:id', function(req, res, next) {
  customerSystem.find({
    id: req.customerId
  }, function(err, customer) {
   // ...
  })
});

/* ..... */

//save the address id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
  req.addressId = req.params.id;
  next();
});

router.use('/:id/addresses', require('./customer-address') )

module.exports = router;
/lib/rest/customer address.js

var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();

router.get('/:id', function(req, res, next) {
  customerSystem.find({
    id: req.params.id
  }, function(err, customer) {
    if (err) {
      res.status( /*correct status code*/ ).send( /*depending on the api return json, xml, ....*/ )
    } else {
      res.send( /*depending on the api return json, xml, ....*/ )
    }
  })
});

router.delete('/:id', function(req, res, next) {
  customerSystem.delete({
    id: req.params.id
  }, function(err) {
    //...
  });
});


router.post('/', function(req, res, next) {
  //...
});

//save the customer id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
  req.customerId = req.params.id;
  next();
});

router.use('/:id/addresses', require('./customer-address') )

module.exports = router;
var customerSystem = require('../customer-system');
var express = require('express');
var router = new express.Router();

router.get('/:id', function(req, res, next) {
  customerSystem.find({
    id: req.customerId
  }, function(err, customer) {
   // ...
  })
});

/* ..... */

//save the address id for the pass to the sub routers
router.use('/:id', function(req, res, next) {
  req.addressId = req.params.id;
  next();
});

router.use('/:id/addresses', require('./customer-address') )

module.exports = router;

您忘记将+'.js'添加到routeObject变量。否则,这是一个有效的解决方案,我将实施它@Rcls节点自动添加
.js
。我根本不会添加
.js
后缀,因为使用较少的
require
后缀的优点是,您可以在以后用模块替换文件(例如,如果您需要将代码拆分为较小的块)。感谢您提供的信息!实际上我把module.exports改成了一个函数,这样我就可以把连接参数传递给它了。实际上,从这里我明白了你的意思。我承认,像这样做要简单得多。我所做的是在server.js中创建了一个“var router=express.router()”,然后将其传递给require(“./api/test”)(路由器,连接)。现在我可以只需要server.js中所有需要的路由文件,就可以得到所有需要的文件。谢谢,这些答案真的帮助我理解node是如何工作的。