consistency
Advanced tools
Comparing version 0.0.1 to 1.0.0
@@ -0,27 +1,32 @@ | ||
'use strict'; | ||
var handler = require('./handler'); | ||
exports.register = function (server, options, next) { | ||
server.ext('onPreHandler', function (request, reply) { | ||
var uriParam = options.uriParam; | ||
var params = request.params || {}; | ||
var headerKey = options.customHeaderKey; | ||
var headers = request.headers; | ||
var acceptNamespace = options.acceptNamespace; | ||
var acceptPattern = new RegExp('^application\/vnd\.' + acceptNamespace + '\.'); | ||
var version; | ||
request.plugins.consistency = {}; | ||
// URI versioning, if enabled | ||
if (options.uriVersioning && request.params.apiVersion && (/^v[0-9]+$/).test(request.params.apiVersion) ) { | ||
request.plugins.consistency.apiVersion = request.params.apiVersion; | ||
return reply.continue(); | ||
if (uriParam && params[uriParam]) { | ||
version = params[uriParam]; | ||
} else if (headerKey && headers[headerKey]) { | ||
version = headers[headerKey]; | ||
} else if (acceptNamespace && headers['accept'] && acceptPattern.test(headers['accept'])) { | ||
version = headers['accept'].replace('application/vnd.' + acceptNamespace + '.', ''); | ||
} else { | ||
version = 'latest'; | ||
} | ||
// Custom Header Versioning, if enabled | ||
if (options.customHeaderVersioning && request.headers['api-version'] && (/^[0-9]+$/).test(request.headers['api-version']) ) { | ||
request.plugins.consistency.apiVersion = 'v' + request.headers['api-version']; | ||
return reply.continue(); | ||
} | ||
// Default to latest | ||
request.plugins.consistency.apiVersion = version; | ||
// Accept Header Versioning, if enabled | ||
var pattern = new RegExp('^application\/vnd\.' + options.acceptNamespace + '\.v[0-9]+$'); | ||
if (options.acceptHeaderVersioning && request.headers['accept'] && pattern.test(request.headers['accept'])) { | ||
request.plugins.consistency.apiVersion = request.headers['accept'].replace('application/vnd.' + options.acceptNamespace + '.', ''); | ||
return reply.continue(); | ||
} | ||
// Default | ||
request.plugins.consistency.apiVersion = 'v1'; | ||
return reply.continue(); | ||
@@ -31,2 +36,4 @@ | ||
handler(server, options); | ||
next(); | ||
@@ -38,2 +45,2 @@ | ||
pkg: require('../package.json') | ||
}; | ||
}; |
{ | ||
"name": "consistency", | ||
"version": "0.0.1", | ||
"version": "1.0.0", | ||
"description": "API versioning plugin for hapi.js", | ||
@@ -23,3 +23,11 @@ "main": "index.js", | ||
}, | ||
"homepage": "https://github.com/shakefon/consistency" | ||
"homepage": "https://github.com/shakefon/consistency", | ||
"dependencies": { | ||
"lodash": "^3.5.0" | ||
}, | ||
"devDependencies": { | ||
"code": "^1.3.0", | ||
"hapi": "^8.4.0", | ||
"lab": "^5.5.0" | ||
} | ||
} |
117
README.md
@@ -0,2 +1,119 @@ | ||
[![npm version](https://badge.fury.io/js/consistency.svg)](http://badge.fury.io/js/consistency) | ||
[![Build Status](https://secure.travis-ci.org/shakefon/consistency.svg)](http://travis-ci.org/shakefon/consistency) | ||
Consistency | ||
----------- | ||
A hapi.js plugin for versioning your API. Borne out of this talk: http://www.slideshare.net/shakefon/hapidays-2014 | ||
##Installation | ||
`npm install consistency` | ||
##Register plugin with your hapi application, provide the option(s) required for version detection. | ||
```js | ||
server.register({ | ||
register: require('consistency'), | ||
options: { | ||
uriParam: 'apiVersion', | ||
acceptNamespace: 'consistencyExample', | ||
customHeaderKey: 'api-version' | ||
} | ||
}, function (err) { | ||
if (err) console.log('Consistency plugin failed to load'); | ||
}); | ||
``` | ||
or, via Glue and manifest: | ||
```js | ||
var manifest = { | ||
connections: [...], | ||
plugins: { | ||
consistency: { | ||
uriParam: 'apiVersion', | ||
acceptNamespace: 'consistencyExample', | ||
customHeaderKey: 'api-version' | ||
} | ||
} | ||
}; | ||
Glue.compose(manifest, function (err, server) { | ||
... | ||
}); | ||
``` | ||
##Versionize your Routes | ||
###Array of handlers | ||
```js | ||
server.route({ | ||
id: 'array', | ||
method: 'GET', | ||
path: '/array', | ||
handler: { | ||
versioned: [ | ||
function(request, reply) { | ||
reply({ | ||
version: '1.0' | ||
}); | ||
}, | ||
function(request, reply) { | ||
reply({ | ||
version: '2.0' | ||
}); | ||
} | ||
] | ||
} | ||
}); | ||
``` | ||
###Object of handlers | ||
```js | ||
server.route({ | ||
id: 'object', | ||
method: 'GET', | ||
path: '/object', | ||
handler: { | ||
versioned: { | ||
'v1.0': function(request, reply) { | ||
reply({ | ||
version: '1.0' | ||
}); | ||
}, | ||
'v2.0': function(request, reply) { | ||
reply({ | ||
version: '2.0' | ||
}); | ||
}, | ||
'v1.5': function(request, reply) { | ||
reply({ | ||
version: '1.5' | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
``` | ||
##Version Matching | ||
A version can be provided with or without the v prefix and can also be provided | ||
using the `latest` keyword which will use the latest versioned endpoint. | ||
Matching of version handlers is cached to remove redundent checks based on the | ||
route method and route path. | ||
If an endpoint has not changed in a specific version of the api, we can omit it | ||
and the matcher will use the version that is closest to the one request. for example | ||
if in version 2 we didn't update the users endpoint a request would return version | ||
1 | ||
If you provide the version in shorthand (v1, 1) it will return greatest version available | ||
for that api version. for example given the versions 1, 1.2, 1.5 providing 1 will return | ||
1.5. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
12771
9
360
1
120
1
3
1
+ Addedlodash@^3.5.0
+ Addedlodash@3.10.1(transitive)