2014-01-26 3 views
6

Derzeit in Entwicklung der API mit Restify und kann immer noch nicht daran gewöhnen, die API-Version in den Headern anzugeben. Es scheint einfach nicht sehr benutzerfreundlich.Restify: API-Version in URL

Gibt es eine Möglichkeit für die Version, Teil der URL zu sein?

Beispiel wäre:

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

Oder noch besser in meinem Fall:

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

Dank

+0

Ich denke, dass abgesehen von nur diejenigen Routen selbst erklärt ('App.get ('/ v1/action', ...) '), Restify unterstützt diese Art von Schema nicht. – robertklep

+0

@robertklep hm das ist, was ich dachte .. zu schlecht – Tom

+0

Es scheint wie es einfacher sein könnte, etwas wie/api/action zu tun? V = 1, obwohl ich noch eine anmutige Art und Weise, damit umzugehen haben. – jczaplew

Antwort

12

Sie können auch Restify verwenden, um Ihre Versionen zu definieren:

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

Und dann diese Middleware verwenden, um mit 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(); 
}); 

schließlich in Ihre Routen können Sie etwas tun:

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 
}); 

Beispiele:

Die obigen Beispiele folgen die Standards, denn wenn Version durch Kopf- oder URL nicht angegeben ist, die letzte Version zeigt.

UPDATE:

Ich habe eine Plugin-API-Versionen in URL zu haben: https://www.npmjs.com/package/restify-url-semver

+0

Danke für die große Antwort würde das auch mit Versionen wie "v1", "v2" usw. funktionieren? – Tom

+0

Sie können 'pieces [0]' erhalten und dann in einen gültigen semver umwandeln, z. v1 bis 1.0.0 oder v1.0 bis 1.0.0, oder v.1.0.0 bis 1.0.0 –

+0

Jetzt können Sie mit v1, v2, v3 usw. verwenden und mit Punkten v1.0, v2.0 hinzufügen , v3.0, v1.2.3, etcetera –

4

Menschen richtig sind, dass es nicht durch restify unterstützt wird, aber ich dachte, ich würde werfen Sie meine Lösung für dieses Problem in den Mix. Ich mache so etwas wie dieses (Warnung, nicht getesteten Code folgen):

Nachdem ich einen Server erstellen, aber VOR ich die Routen erklären, melde ich einen benutzerdefinierten Parser die URL-style-Version Spezifizierer in ein übersetzen HTTP-style specifier:

server.use(versionParser); 

Und versionParser.js sieht ungefähr so ​​aus:

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(); 
} 

Auf diese Weise können die restify Routen der Accept-Header-Version überprüfen, da sie von Natur aus tun.

Nebenbei bemerkt: Der semver Teil ist auf diese Antwort wahrscheinlich nicht relevant, aber ich wollte, dass die API-Version in der URL zu überprüfen, ein gültiger semver Wert war, da es Flexibilität in den URL-Werten so ermöglicht, dass ein Benutzer könnte Nutzen Sie die Flexibilität von restify in Versionsspezifizierern.

+0

Injizieren der Anfrage, interessant. Ich denke, dass Sie ein kleines bisschen mehr Arbeit tun müssten, um Fälle zu kümmern, wenn Leute tatsächlich den Versionsheader spezifizieren, und auch ein wenig Gedanken brauchen, die Unterstützungsversionen im Format xxx aber ansonsten, gute und wirkungsvolle Antwort – Tom

+1

@Tom gut stützen Gedanken. semver.valid erzwingt, dass es x.x.x ist, also würde ich _think_ das abdecken. Was die Überprüfung betrifft, ob sie es anfangs in den Accept-Version-Header gesetzt haben, ist das ein guter Gedanke, den ich im Fall einer Migration von einem Format zum anderen als besonders nützlich ansehen könnte. – thataustin

+0

Ehrlich gesagt habe ich noch nicht sverver verwendet also nicht genau was es macht. Aber in meinem Fall wäre es auch ohne es ziemlich einfach. Ich sehe nicht, wenn ich andere Version als 1, 2 usw. verwenden würde. So einfache Version + '. 0.0' würde tun – Tom