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是如何工作的。