RESTful Services中特定方案的最佳实践

时间:2011-07-05 18:41:01

标签: .net wcf web-services rest

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

  1. 如果我有一个可以使用ID或日期(20110705)访问的实体,那么用于访问该实体的url约定的最佳做法是什么?

    • 获取:/myEntities/{date}/myEntities/{id}? (哪个 service将解析{object}以检查它是日期还是id。

    • 获取:/myEntities/date/{date}/myEntities/id/{id} *?

  2. 在WCF Rest中,我也可以/myEntities/?date={date}/myEntities/?id={id},这是REST的一个很好的做法吗?换句话说,就最佳做法而言,使用?date={date}代替date/{date}/是否可以接受,因为它只是个人偏好?

  3. 提前致谢。

3 个答案:

答案 0 :(得分:8)

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

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

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

无需明确ID选项;这是假设的。

关于#2;我个人不喜欢这种语法:/myEntities/?date={date} 如果它在WCF中作为URI模板实现 - 因为如果您有多个参数,则假设参数的顺序可以被推挤周围 - 但他们不能与URI模板。但是,作为标准的查询字符串参数,这是完全可以接受的,并且在各地都可以完成 - 谷歌,雅虎,亚马逊和其他人都使用这种风格。 如果有的话,这正是“查询字符串”的意思 - 查询的参数......这正是您在通过 __ 检索实体时所做的事情。

(但我和其他人会说的一样好奇。)

答案 1 :(得分:6)

/myEntities/date/{date}应根据您的应用使用301或307重定向到/myEntities/{id}。这减少了由于多个缓存副本导致数据不同步的可能性,并使客户明白/myEntities/date/*只是一个备用索引,而不是一组独立资源(正如他们可能正确期望的那样)由于HTTP URI的分层特性,因此不重定向。

答案 2 :(得分:0)

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

这也意味着,您永远不会有两个唯一标识相同资源的网址。

现在这并不意味着您无法从两个不同的网址访问相同的资源。你想要这样做有很多原因。您需要确定一些事项。

对于任何消费你API的人来说,你应该很容易理解它。您列出的选项不会这样做。

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

因此,问问自己这两种情况中的每种情况都会解决,然后它可能会变得明显。

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

因此,问问自己能否将日期用作网址的一部分,或者将其作为查询字符串过滤器添加到集合上是否最重要。这样你就可以实际公开一个往返日期过滤器,这可能更具价值,也更直观。

或者考虑以下内容:

/years可能会公开年份对象列表

{
  "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。但这根本不是一件容易的事。