你如何在Node/Express应用程序中处理api版本

Pao*_*.nl 31 versioning api node.js express

我是Node.js的新手,我面临以下问题.

我的中间件以链接api/v1/login和一堆端点开始.然后api/v1.1介绍了另外两个端点.api/v1.2现在是最后一个,并获得了一些新的终点.

我该如何以有效的方式处理这个api版本?如何从可用于下一版本的版本中创建端点?

Ita*_*Ale 49

首先,如果您正在构建REST API并且刚刚开始,您可能需要考虑使用Restify而不是Express.虽然Express当然可以用于此目的,但Restify的设计符合REST API服务器的所有要求:标准化异常,API版本控制等.

如上所述,我相信你的第一个问题是设计缺陷.仅当新API 与先前版本向后兼容时,即当主要版本增加时(例如从v1到v2),才应创建单独的端点.这应该尽可能少发生!
如果您只是添加新功能或进行其他不会破坏现有代码的调整,则不应创建不同的端点.因此,您不应该为v1.1,v1.2等创建端点,前提是所有与v1.0一起使用的代码也适用于v1.1(如果不是这样的话,那么您将引入更改,不向后兼容,因此您应该考虑将版本更改为v2).
请注意,每次引入向后不兼容的更改时,所有用户都需要更新其代码,并且您必须支持旧API一段时间,以便让所有用户都能更新.对于您(您需要维护旧的代码库)和您的用户(他们需要更新他们的代码),这是一个昂贵的过程,因此应该尽可能不频繁地发生.此外,对于每个版本,您需要编写文档,创建示例等.
(底线:花费大量时间设计API服务器,以便尽可能长时间不进行向后不兼容的更改)

要回答您的问题,那么,一种方法可以是为每个API集(每个版本)创建子文件夹,然后相应地设置路由器.例如,您的项目将如下所示:

/
-- app.js
-- routes/
-- -- v1/
-- -- -- auth.js
-- -- -- list.js
-- -- v2/
-- -- -- auth.js
-- -- -- list.js
Run Code Online (Sandbox Code Playgroud)

这不应该是一个问题:由于v2与v1不向后兼容,很可能这两个文件有很大不同.
然后,在Express上只需相应地使用路由器.例如:

app.get('/v1/list/:id', v1.list)
app.all('/v1/auth', v1.auth)

app.get('/v2/list/:id', v2.list)
app.all('/v2/auth', v2.auth)
Run Code Online (Sandbox Code Playgroud)

但是,还有其他选择.例如,更优雅(虽然稍微高级)的解决方案可以是:http://j-query.blogspot.ca/2013/01/versioned-apis-with-express.html

注意这个方法

虽然,根据semver,如果您计划在v1和v2之间实现许多实质性差异(重用代码的可能性很小),那么每个向后不兼容的更改都应该看到API主要版本的增加,那么这个方法不适合你.

在最后一种情况下,您可能希望为v1和v2创建两个单独的Node.js应用程序,然后使用nginx配置正确的路由.版本控制不会在应用程序级别完成(每个应用程序将响应'/ auth','/ list /:id'和NOT'/ v1/auth','/ v1/list:id'等),但是nginx将前缀为"/ v1 /"的请求转发给一个工作服务器,将前缀为"/ v2 /"的请求转发给另一个工作服务器.


pra*_*jam 11

像restify这样的框架更适合api版本化,但是如果你使用express并且需要一个轻量级的模块来版本化你的路由,试试这个npm模块https://www.npmjs.com/package/express-routes-versioning

模块允许单独对单个路径进行版本控制.它支持服务器上的基本semver版本控制以匹配多个版本.(如果需要的话).它与特定的版本控制策略无关,并允许应用程序设置版本.

示例代码

var app = require('express')();
var versionRoutes = require('express-routes-versioning')();
app.listen(3000);
app.use(function(req, res, next) {
    //req.version is used to determine the version
   req.version = req.headers['accept-version'];
   next();
});
app.get('/users', versionRoutes({
   "1.0.0": respondV1,
   "~2.2.1": respondV2
}));

// curl -s -H 'accept-version: 1.0.0' localhost:3000/users
// version 1.0.0 or 1.0 or 1 !
function respondV1(req, res, next) {
   res.status(200).send('ok v1');
}

//curl -s -H 'accept-version: 2.2.0' localhost:3000/users
//Anything from 2.2.0 to 2.2.9
function respondV2(req, res, next) {
   res.status(200).send('ok v2');
}
Run Code Online (Sandbox Code Playgroud)