Шаблоны URI: Есть ли реализация rfc-6570 в javascript?
Я использую node и выражаю. Чтобы зарегистрировать контроллер, я вызываю:
app.get('/user/:id', function (req, res) {...});
Но я хотел бы сделать это rfc-6570 способом:
app.get('/user/{id}', function (req, res) {...});
Я искал только реализацию на python в коде google, но ничего не нашел (кроме мертвой ссылки в коде google для http://www.snellspace.com/wp/?p=831) для JavaScript.
Шаблоны URI в целом не так просты, как кажется на первый взгляд. Взгляните на примеры в RFC.
PS: Мне тоже нужны шаблоны URI на клиенте.
Ответы
Ответ 1
Я очистил список реализаций в http://code.google.com/p/uri-templates/wiki/Implementations - есть JS в https://github.com/marc-portier/uri-templates, но я не уверен, реализует ли он RFC, и каково его качество.
Обратите внимание, что мы начали публиковать тесты здесь: https://github.com/uri-templates/uritemplate-test
Итак, если вы хотите проверить это, вы можете начать там.
Ответ 2
По состоянию на июнь 2014 года эти реализации JavaScript выглядят наиболее полно (уровень 4 спецификации) и проверено. Все три поддерживают оба браузера и node.js.
Ответ 3
Что касается части экспресс-маршрутизатора, я бы рекомендовал использовать ваши шаблоны uri в гиперсхеме (читать дальше)...
Тогда вы также можете воспользоваться регулярным выражением для своего маршрутизатора, который поддерживает express.js.
Что касается решения параметров, вам нужна реализация RFC 6570, например https://github.com/geraintluff/uri-templates...
Вот какой-то код .js, чтобы проиллюстрировать переписывание гиперссылки
ИСПОЛЬЗОВАНИЕ RFC 6570 для преобразования его в экспресс-маршрутизатор js:
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));
});