Restify:URL中的API版本

时间:2014-01-26 15:59:18

标签: node.js routes restify

目前正在开发具有restify的API,但仍无法习惯在标头中指定API版本。它似乎不是非常用户友好。

版本是否有任何方式成为网址的一部分?

示例是:

http://domain.com/api/v1/action

在我的情况下甚至更好:

http://api.domain.com/v1/action

由于

2 个答案:

答案 0 :(得分:14)

您也可以使用Restify来定义您的版本:

var server = restify.createServer({
    name: 'myAPI',
    versions: ['1.0.0', '2.0.0']
});

然后将此中间件与server.pre

一起使用
server.pre(function (req, res, next) {
    var pieces = req.url.replace(/^\/+/, '').split('/');
    var version = pieces[0];

    // only if you want to use this routes:
    // /api/v1/resource
    // /api/v1.0/resource
    // /api/v1.0.0/resource
    if (!semver.valid(version)) {
        version = version.replace(/v(\d{1})\.(\d{1})\.(\d{1})/, '$1.$2.$3');
        version = version.replace(/v(\d{1})\.(\d{1})/, '$1.$2.0');
        version = version.replace(/v(\d{1})/, '$1.0.0');
    }

    if (semver.valid(version) && server.versions.indexOf(version) > -1) {
        req.url = req.url.replace(version + '/', '');
        req.headers['accept-version'] = version;
    }

    return next();
});

最后,在您的路线中,您可以执行以下操作:

server.get({ path: '/resource/:id', version: '1.0.0' }, function () {
  // send object in version 1.0.0
});

server.get({ path: '/resource/:id', version: '2.0.0' }, function () {
  // send object in version 2.0.0
});

示例:

以上示例遵循标准,因为如果未通过标头或网址指定版本,则显示最后一个版本。

<强>更新

我制作了一个插件,以便在网址中包含API版本: https://www.npmjs.com/package/restify-url-semver

答案 1 :(得分:4)

人们是正确的,它不是得到了解决方案的支持,但我认为我会把这个问题的解决方案投入到混合中。我正在做这样的事情(警告,未经测试的代码可以遵循):

创建服务器后, BEFORE 我声明了路由,我注册了一个自定义解析器,将url样式的版本说明符转换为HTTP样式的说明符:

server.use(versionParser);

versionParser.js看起来像这样:

var semver = require('semver');
var restify = require('restify');

module.exports = function (req, res, next) {

    // we expect every request to have the form "/api/[api-version]/..."
    // verify that the api-version is a valid semver value
    var urlPieces = req.url.replace(/^\/+/, '').split('/');
    var api = urlPieces[0];
    var apiVersion = urlPieces[1];

    if (api !== 'api' || !semver.valid(apiVersion)) {
        return next(new restify.InvalidContentError({message: "Invalid Version Specifier"}));
    }

    req.header('Accept-Version', apiVersion);
    return next();
}

这样,restify路由可以自然地检查Accept-Version标头。

Sidenote :semver部分可能与此答案无关,但我想验证URL中的API版本是否为有效的semver值,因为它允许灵活调整URL值等用户可以利用版本说明符中的restify灵活性。