Node.js 如何处理Node/Express应用程序中的api版本

Node.js 如何处理Node/Express应用程序中的api版本,node.js,api,express,versioning,Node.js,Api,Express,Versioning,我是Node.js的新手,我面临以下问题 我的中间件从链接api/v1/login和一组端点开始。 然后api/v1.1引入了另外两个端点api/v1.2现在是最后一个,并获得了一些新的端点 如何以有效的方式处理此api版本控制?如何使某个版本的端点也可用于下一个版本 我猜您的API违反了REST约束,至少肯定违反了无状态约束。检查REST的统一接口约束。它告诉您如何将客户端与API的实现分离。这样做之后,您可能就不再需要版本控制了 如果您不想应用REST约束,那么我认为URL应该只包含主版本号

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

我的中间件从链接
api/v1/login
和一组端点开始。 然后
api/v1.1
引入了另外两个端点
api/v1.2
现在是最后一个,并获得了一些新的端点


如何以有效的方式处理此api版本控制?如何使某个版本的端点也可用于下一个版本

我猜您的API违反了REST约束,至少肯定违反了无状态约束。检查REST的统一接口约束。它告诉您如何将客户端与API的实现分离。这样做之后,您可能就不再需要版本控制了

如果您不想应用REST约束,那么我认为URL应该只包含主版本号(表示不向后兼容的更改)。之后,您可以定义特定于供应商的MIME类型或内容类型参数,如果需要,您可以在其中描述次要版本号、审阅版本号和生成版本号。因此,您的客户端应该发送带有这些版本参数的accept和content-type头


如果你想同时支持多个版本,你必须为他们中的每一个编写文档。

首先,如果你正在构建一个REST API,而你刚刚开始,你可能想考虑使用而不是Express。尽管Express当然可以用于此目的,但Restify的设计满足RESTAPI服务器的所有要求:标准化异常、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
这应该不是问题:因为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)
不过,还有其他选择。例如,一个更优雅(尽管稍微高级)的解决方案可以是:

关于此方法的注释 然而,根据semver的说法,每一个向后不兼容的更改都会增加API的主要版本,如果您计划在v1和v2之间实现许多实质性的差异(重用代码的可能性很小),那么这种方法不适合您


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

restify等框架更适合api版本控制,但是,如果您正在使用express,并且需要一个轻量级模块来对路由进行版本设置,请尝试此npm模块

模块允许单独对各个路由进行版本控制。它支持服务器上的基本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');
}

对/用户或/users/list都是我所称的端点的例子。事实上,我创建了API的新版本,只是因为我添加了新功能,这就是造成混淆的原因。我添加的所有更改都是向后兼容的,所以从我阅读的内容来看,在这种情况下,添加新版本是没有必要的。如果我遵循您的概念,那么我的结构将来将如下所示:
/--controllers/--v1/--v2/--helpers/--v1/--v2/--middleware/--v2/--models/--v1/--v2/
@user1791139您不会希望这样做。请参阅我的更新答案,了解您在这种情况下可以做些什么。如果我将所有这些文件复制到这里,而不是那里,这不会产生大量重复。考虑一下这个场景,如果我只是在V1 API中有一个小的变化(让我们说Authmodel),并要求在V2中用V1中的所有现有的东西来反映这个变化。是否有其他方法来处理此问题?您将控制器和服务放在其中的什么位置?它是在v1文件夹内还是在v1文件夹外