【问题标题】:URI templates: Is there an rfc-6570 implementation in javascript?URI 模板:javascript 中是否有 rfc-6570 实现?
【发布时间】:2012-05-05 17:12:43
【问题描述】:

我正在使用节点和快递。要注册我调用的控制器:

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

但我想以rfc-6570 的方式进行:

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

我在谷歌代码上搜索了一个 python 实现,但没有找到任何 JavaScript 代码(除了谷歌代码到 http://www.snellspace.com/wp/?p=831 的死链接)。

一般来说,URI 模板并不像第一眼看上去那么容易。查看 RFC 中的示例。

PS:我也需要客户端上的 URI 模板。

【问题讨论】:

  • 那个 RFC 才两个月大;如果暂时没有任何合规的实现,我不会感到惊讶......
  • 出于好奇,您为什么要使用该 RFC 而不是 Express 提供的表单?
  • 首先,rfc 只有 2 个月大。但草稿大约有 3 年的历史。
  • 第二,我想使用RFC的方式,因为我在服务器上有一个混合环境:express和java/spring。 Spring 正在使用 rfc 样式(非常接近)。我想在 spring 和 express 中使用相同的模板——当然,在用户代理中也是如此。 rfc 方式比 express/(ruby?) 方式更具表现力
  • 最后第三,如果没有实现,我会创建一个;-)

标签: javascript node.js express uritemplate


【解决方案1】:

我一直在清理 http://code.google.com/p/uri-templates/wiki/Implementations 的实现列表 - https://github.com/marc-portier/uri-templates 有一个 JS 列表,但我不确定它是否实现了 RFC,也不知道它的质量如何。

请注意,我们已经开始在这里发布测试: https://github.com/uri-templates/uritemplate-test

所以如果你想检查它,你可以从那里开始。

【讨论】:

  • 谢谢!我将在实施时集成测试。 marc portier 的工作很好,但它只能解析一个模板并将其扩展为一个 URI。但困难的部分是使用 uriTemplate 提取给定 URI 的变量。正如您在 rfc 中 1.5 的最后一段中所写:“某些 URI 模板可以反向使用以实现变量匹配:将模板与完全形成的 URI 进行比较,以便从该 URI 中提取可变部分并分配它们到命名变量。”
  • @afx 你有没有在某个地方实现它?我想做类似的事情,也必须在任何可以加入的地方创建一个?
  • @afx 对不起,不知怎的错过了你可能是来自 github 的 fxa ;)
  • 感谢 @afx 开发这个库! :)
【解决方案2】:

截至 2014 年 6 月,这些 JavaScript 实现似乎最完整(规范的第 4 级)和tested。这三个也都支持浏览器和node.js。

【讨论】:

    【解决方案3】:

    关于快速路由器部分,我建议在 hyperschema (read more) 中使用您的 uri 模板 ...

    然后,您还可以从 express.js 支持的路由器的正则表达式中受益。 关于解析参数,您需要一个 RFC 6570 实现,例如 https://github.com/geraintluff/uri-templates ...

    这里有一些 .js 代码来说明 hyperschema 的重写 使用 RFC 6570 将其转换为 express 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));
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-22
      • 2020-07-25
      • 2011-07-29
      • 1970-01-01
      • 2011-11-20
      • 2023-01-13
      相关资源
      最近更新 更多