2012-05-05 12 views
11

Ich benutze Knoten und Express. Um einen Controller registrieren Ich nenne:URI-Vorlagen: Gibt es eine RFC-6570-Implementierung in Javascript?

app.get('/user/:id', function (req, res) {...}); 

Aber ich möchte es die rfc-6570 Weise tun:

app.get('/user/{id}', function (req, res) {...}); 

ich in Python nur eine Implementierung gegoogelt auf Code google, aber nichts gefunden (außer den Toten Link auf Google Code zu http://www.snellspace.com/wp/?p=831) für JavaScript.

URI Templating im Allgemeinen ist nicht so einfach wie es auf den ersten Blick aussieht. Schauen Sie sich die Beispiele im RFC an.

PS: Ich werde die URI-Vorlagen auch auf dem Client benötigen.

+0

Das RFC erst zwei Monate alt ist; Ich würde nicht überrascht sein, wenn es für eine Weile keine konforme Implementierungen gibt ... – maerics

+0

Aus Neugier, warum möchten Sie diesen RFC anstelle des Formulars verwenden, das Express bietet? – maerics

+0

Erstens ist das RFC nur 2 Monate alt. Aber die Entwürfe sind ungefähr 3 Jahre alt. – afx

Antwort

7

Ich habe die Umsetzungsliste bei http://code.google.com/p/uri-templates/wiki/Implementations aufgeräumt - es gibt eine JS one bei https://github.com/marc-portier/uri-templates, aber ich bin mir nicht sicher, ob es den RFC implementiert, noch was seine Qualität ist.

Bitte beachte, dass wir publishing Tests begonnen haben hier: https://github.com/uri-templates/uritemplate-test

Also, wenn Sie es überprüfen möchten, können Sie es starten konnte.

+0

Danke! Ich werde die Tests bei der Implementierung integrieren. Die Arbeit von marc portier ist in Ordnung, aber es kann nur eine Vorlage analysieren und sie zu einer URI erweitern. Aber der schwierige Teil besteht darin, die Variablen eines gegebenen URI mit einem uriTemplate zu extrahieren. Wie Sie im letzten Absatz von 1.5 in der RFC geschrieben: "Einige URI-Vorlagen können umgekehrt für den Zweck der Variablen verwendet werden: Vergleichen Sie die Vorlage mit einem vollständig gebildeten URI, um extrahieren Sie die variablen Teile aus diesem URI und Weisen Sie sie den genannten Variablen zu. " – afx

+0

@afx Haben Sie es irgendwo implementiert? Ich würde gerne eine ähnliche Sache machen und muss auch eine erstellen, wo auch immer ich beitreten kann? – Almad

+0

@afx Sorry, irgendwie verpasst, dass du wahrscheinlich fxa von github bist;) – Almad

4

Seit Juni 2014 scheinen diese JavaScript-Implementierungen am vollständigsten (Level 4 der Spezifikation) und tested. Alle drei unterstützen auch den Browser und node.js.

0

In Bezug auf die ausdrückliche Router Teil würde ich empfehlen, Verwenden Sie Ihre URI-Vorlagen innerhalb einer (read more) ...

Dann könnten Sie auch von Regex für Ihren Router profitieren, die express.js unterstützt. In Bezug auf die Parameter Lösung Sie eine RFC 6570 Implementierung wie https://github.com/geraintluff/uri-templates brauchen ...

Hier ist ein Code Js das Umschreiben eines hyperschema zur Veranschaulichung über RFC 6570 es auf ein Express.js Router zu konvertieren:

var hyperschema = { 
    "$schema": "http://json-schema.org/draft-04/hyper-schema", 
    "links": [ 
    { 
     "href": "{/id}{/ooo*}{#q}", 
     "method": "GET", 
     "rel": "self", 
     "schema": { 
     "type": "object", 
     "properties": { 
      "params": { 
      "type": "object", 
      "properties": { 
       "id": {"$ref": "#/definitions/id"} 
      }, 
      "additionalProperties": false 
      } 
     }, 
     "additionalProperties": true 
     } 
    } 
    ], 
    "definitions": { 
    "id": { 
     "type": "string", 
     "pattern": "[a-z]{0,3}" 
    } 
    } 
} 
var deref = require('json-schema-deref'); 
    var tv4 = require('tv4'); 
    var url = require('url'); 
    var rql = require('rql/parser'); 

// DOJO lang AND _ 
function getDottedProperty(object, parts, create) { 
    var key; 
    var i = 0; 

    while (object && (key = parts[i++])) { 
     if (typeof object !== 'object') { 
      return undefined; 
     } 
     object = key in object ? object[key] : (create ? object[key] = {} : undefined); 
    } 

    return object; 
} 
function getProperty(object, propertyName, create) { 
    return getDottedProperty(object, propertyName.split('.'), create); 
} 
function _rEscape(str) { 
    return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); 
} 

function getPattern(k, ldo, customCat) { 
    // ...* = explode = array 
    // ...: = maxLength 
    var key = ((k.slice(-1) === '*') ? k.slice(0,-1) : k).split(':')[0]; 
    var cat = (customCat) ? customCat : 'params'; // becomes default of customCat in TS 
    var pattern = ''; 
    if (typeof ldo === 'object' && ldo.hasOwnProperty('schema')) { 
    var res = getProperty(ldo.schema, ['properties',cat,'properties',key,'pattern'].join('.')); 
    if (res) { 
     console.log(['properties',cat,'properties',key,'pattern'].join('.'),res); 
     return ['(',res,')'].join(''); 
    } 
    } 
    return pattern; 
} 
function ldoToRouter(ldo) { 
    var expression = ldo.href.replace(/(\{\+)/g, '{') // encoding 
    .replace(/(\{\?.*\})/g, '') // query 
    .replace(/\{[#]([^}]*)\}/g, function(_, arg) { 
     // crosshatch 
     //console.log(arg); 
     return ['(?:[/]*)?#:',arg,getPattern(arg,ldo,'anchor')].join(''); 
    }) 
    .replace(/\{([./])?([^}]*)\}/g, function(_, op, arg) { 
     // path seperator 
     //console.log(op, '::', arg, '::', ldo.schema); 
     return [op,':',arg,getPattern(arg,ldo)].join(''); 
    }); 
    return {method: ldo.method.toLowerCase(), args:[expression]}; 
} 

deref(hyperschema, function(err, fullSchema) { 
    console.log('deref hyperschema:',JSON.stringify(fullSchema)); 
    var router = fullSchema.links.map(ldoToRouter); 

    console.log('router:',JSON.stringify(router)); 
});