Restify – Specify API Version in URL

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.