Node.js API 设计和路线处理
Node.js API design and route handling
我不太确定该用什么标题,但我是 Node.js
的新手。我刚刚在 GitHub 上找到了一个简洁的 REST API 项目来实现,但我不确定如何将所有 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?
but I'm not sure how I can split all GET and POST etc. to separate files.
组织路由的一种方法是为每个路由创建一个单独的对象,其中包含处理程序(由 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 !"});
},
// ...
然后你可以在 handleRoutes
方法中加载所有这些:
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_ROUTER
来调用此代码:
// initialize the api (and handle the routes internally)
var Api = new require('./api.js')(router, connection, md5);
如果您实施 RESTful API,那么您应该记住,这只是您提供数据的一种方式,您可能希望在将来更改它,从API 大多数时候只是翻译层。
通常你会根据资源拆分你的代码,处理请求的代码不会有那么多逻辑,它只会接受请求并在内部传递给你API。为此,如果您已经使用 express.js
或类似的库,那么您实际上并不需要额外的层。
在 express app.use([path,] function [, function...])
中,已经提供了模块化代码所需的功能。对于每个资源,您将创建一个自己的 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;
./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.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;
我不太确定该用什么标题,但我是 Node.js
的新手。我刚刚在 GitHub 上找到了一个简洁的 REST API 项目来实现,但我不确定如何将所有 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?
but I'm not sure how I can split all GET and POST etc. to separate files.
组织路由的一种方法是为每个路由创建一个单独的对象,其中包含处理程序(由 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 !"});
},
// ...
然后你可以在 handleRoutes
方法中加载所有这些:
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_ROUTER
来调用此代码:
// initialize the api (and handle the routes internally)
var Api = new require('./api.js')(router, connection, md5);
如果您实施 RESTful API,那么您应该记住,这只是您提供数据的一种方式,您可能希望在将来更改它,从API 大多数时候只是翻译层。
通常你会根据资源拆分你的代码,处理请求的代码不会有那么多逻辑,它只会接受请求并在内部传递给你API。为此,如果您已经使用 express.js
或类似的库,那么您实际上并不需要额外的层。
在 express app.use([path,] function [, function...])
中,已经提供了模块化代码所需的功能。对于每个资源,您将创建一个自己的 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;
./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.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;