Recently, I started a project to build an API for the Utah DABC‘s online beer inventory.
After researching a few NodeJS REST frameworks, I selected Restify because it’s dead simple to use, supports CORS and versioning out of the box, and has a Redis-based response cache plugin available.
I wanted to specify the API version in the URL, but Restify only natively supports the Accept-Version
HTTP header.
This Stack Overflow answer suggested a middleware approach to map a version URL prefix to the Accept-Version
header, but it didn’t work correctly for “partial” version paths like v1
and v1.0
.
Here’s the version I modified to work as I expected:
// allow path based API versioning // based on https://stackoverflow.com/a/29706259 server.pre(function (req, res, next) { var pieces = req.url.replace(/^\/+/, '').split('/'), pathVersion = pieces[0], semVersion = semver.valid(pathVersion); // only if you want to use this routes: // /api/v1/resource // /api/v1.0/resource // /api/v1.0.0/resource if (!semVersion) { semVersion = pathVersion.replace(/v(\d{1})\.(\d{1})\.(\d{1})/, '$1.$2.$3'); semVersion = semVersion.replace(/v(\d{1})\.(\d{1})/, '$1.$2.0'); semVersion = semVersion.replace(/v(\d{1})/, '$1.0.0'); } if (semver.valid(semVersion) && server.versions.indexOf(semVersion) > -1) { req.url = req.url.replace(pathVersion + '/', ''); req.headers['accept-version'] = semVersion; } return next(); });
Note: this approach requires node-semver
.