.net RESTful服务中特定场景的最佳实践

.net RESTful服务中特定场景的最佳实践,.net,wcf,web-services,rest,.net,Wcf,Web Services,Rest,我有两个简短的问题,我只想得到社区的意见- 如果我有一个可以通过ID或日期(20110705)访问的实体,那么访问该实体的url约定的最佳实践是什么 获取:/myEntities/{date}和/myEntities/{id}?(该 服务将解析{object}以检查它是日期还是id 获取:/myenties/date/{date}和/myenties/id/{id}* 在WCF Rest中,我也可以做/myEntities/?date={date}和/myEntities/?id={id},

我有两个简短的问题,我只想得到社区的意见-

  • 如果我有一个可以通过ID或日期(20110705)访问的实体,那么访问该实体的url约定的最佳实践是什么

    • 获取:
      /myEntities/{date}
      /myEntities/{id}
      ?(该 服务将解析{object}以检查它是日期还是id

    • 获取:
      /myenties/date/{date}
      /myenties/id/{id}
      *

  • 在WCF Rest中,我也可以做
    /myEntities/?date={date}
    /myEntities/?id={id}
    ,这是Rest的一个好实践吗?换句话说,就最佳实践而言,使用
    ?date={date}
    而不是
    date/{date}/
    是否可以接受,就好像这只是个人偏好一样


  • 提前谢谢。

    我觉得这在很大程度上取决于偏好和风格

    话虽如此,我个人更喜欢:


    /myEntities/date/{date}
    /myEntities/{id}

    不需要显式地使用ID选项;这是假定的

    关于#2;我个人不喜欢这种语法:
    /myenties/?date={date}
    如果它在WCF中作为URI模板实现的话——因为如果你有多个参数,那么假设参数的顺序可能会有冲突——但它们不能与URI模板冲突。但是,作为标准的查询字符串参数,这是完全可以接受的,并且在所有地方都可以做到——谷歌、雅虎、亚马逊n、 其他人都使用这种风格。 如果有什么区别的话,这正是“查询字符串”的含义-查询的参数…这正是您在通过\uu\u检索实体时所做的操作


    (但我和你一样好奇别人会怎么说)。

    /myEntities/date/{date}
    应该重定向到
    /myEntities/{id}
    根据应用程序的需要使用301或307。这降低了由于多个缓存副本而导致数据不同步的可能性,并向客户端表明,
    /myenties/date/*
    只是一个备用索引,而不是一组独立的资源(由于HTTP URI的层次结构,如果您没有重定向,他们可能会正确地期望)。

    资源有一个标识URL(如果您愿意,则为自己的URL)。这绝对不能更改。这也意味着,如果您在某一点上冒险更改该id,则该id不是您在url中使用的id。如果您冒险回收该id,则绝对不应使用该id

    这也意味着,您将永远不会有两个唯一标识同一资源的URL

    这并不意味着你不能从两个不同的URL访问同一个资源。有很多原因让你这么做。你只需要确定几件事

    您应该让任何使用您的API的人都能很容易地理解正在发生的事情。您列出的选项并不能做到这一点

    它基本上归结为建模,并确保您的内部模型不会流入公共api。您可能有一个重载方法,可以将id或日期作为输入参数,但这并不意味着您应该公开该重载

    所以问问自己,这两种情况各自解决了什么样的情况,然后它可能会变得显而易见

    我也不喜欢史蒂夫的建议。消费者怎么知道你可以写“日期”而不是id,然后突然按日期访问?这不是直观的

    因此,问问自己,能够将日期作为url的一部分是至关重要的,还是将其添加为集合中的查询字符串筛选器更好。这样,您就可以实际公开“收件人”和“发件人”日期筛选器,这可能更有价值,也更直观

    备选地考虑以下一些事情:

    /years
    ,它可能会公开year对象的列表

    {
      "year": 2015,
      "entities": "https://api.myapp.com/years/2015/entities",
      "months": [
          {
            "month": 1,
            "name": "January",
            "entities": "https://api.myapp.com/years/2015/months/1/entities",
            "self": "https://api.myapp.com/years/2015/months/1"
          },
           ... array of month objects
      ],
      "self": "https://api.myapp.com/years/2015"
    }
    
    /years/2015/months/1
    是月份对象的一个示例

    {
      "month": 1,
      "name": "January",
      "entities": "https://api.myapp.com/years/2015/months/1/entities",
      "self": "https://api.myapp.com/years/2015/months/1"
    }
    
    entities属性具有指向按日期筛选的实体集合的链接


    但这一切都取决于您的具体问题。请记住让界面直观,不要让您的内部建模渗透到您的公共api中。但这根本不是一项容易的任务。

    感谢您的快速回复!因此您建议如果我使用date={date},我不应该使用URI模板(哪些映射到web方法的参数)?并将它们作为查询字符串对象进行解析?badallen;老实说,我不确定WCF是否有解析查询字符串参数的内置方法…最坏的情况是,您可以在URI模板的末尾使用
    […]?{querystring}
    ,并使用一个众所周知的函数来解析查询字符串(我认为ASP.NET框架中甚至有一个你可以访问的)我反对的是:
    […]?date={data}和otherParameter={otherParameter}
    。干杯!我接受所有形式的/date/(date),/id/(date或id),/date=(date),/id=(id)但是,在将URI返回给用户时,请使用Steve建议的表单。如果不需要,为什么要限制输入?