【问题标题】:REST best practice for getting a subset list获取子集列表的 REST 最佳实践
【发布时间】:2011-01-19 15:23:20
【问题描述】:

我在REST - complex applications 阅读了这篇文章,它回答了我的一些问题,但不是全部。

我正在设计我的第一个 REST 应用程序,需要将“子集”列表返回给 GET 请求。以下哪个更“RESTful”?

/patients;listType=appointments;date=2010-02-22;user_id=1234

/patients/appointments-list;date=2010-02-22;user_id=1234

甚至

/appointments/2010-02-22/patients;user_id=1234

我需要返回大约十几个不同的列表。在其中一些中,会有几个过滤参数,我不想在我的服务器代码中使用大的“if”语句来根据存在的参数选择子集。例如,我可能需要某个特定医生的所有患者,其中覆盖医生是另一位医生,而主治医生是另一位医生。我可以选择

/patients;rounds=true;specific_id=xxxx;covering_id=yyyy;primary_id=zzzz

但这需要复杂的分支逻辑才能获得正确的列表,其中要求特定子集(轮列表)将实现相同的目标。

请注意,我需要使用矩阵参数而不是查询参数,因为我需要在 URL 的多个级别进行过滤。我使用的框架(RestEasy),完全支持矩阵参数。

【问题讨论】:

  • 我认为它们都可能是 RESTish,但 URL 只是 RESTish 的一部分。我的选择是 /appointments/patients/user_id=1234/date=2010-02-22,这样您就可以取消日期并获取该用户 ID 的所有患者预约。

标签: rest


【解决方案1】:

拉尔夫,

特定的 URI 模式与您的应用程序的 RESTful 程度这个问题是正交的。

关于 RESTfulness 重要的是客户端发现如何在运行时构造 URI。这可以通过表单或 URI 模板来实现。两个超媒体控件都告诉客户端可以使用哪些参数以及将它们放在 URI 中的什么位置。

为了让这个以 RESTful 方式工作,客户端和服务器必须在设计时知道可能的参数。这通常是通过使它们成为链接关系规范的一部分来实现的。

例如,您可以定义一个“我的子集”链接关系以具有链接到集合子集的含义,并使用它定义以下参数:

列表类型、日期、用户 ID。

在规范可以用作的链接模板中

注意 URI 中的实际参数名称是如何与指定的参数名称分离的。 userID 的值后期绑定到 URI 参数 user_id。

这使得 URI 参数名称可以在不影响客户端的情况下更改。

您可以查看 OpenSearch 描述文档 (http://www.opensearch.org) 以了解这是如何在实践中完成的。

实际上,您应该能够在您的用例中充分利用 OpenSearch。尤其是预定义查询的能力将允许您在“表单”中描述特定的子集。

但你自己看看然后再问:-)

一月

【讨论】:

  • 我正在浏览 opensearch 文档。您是否建议通过调用服务器上的其他 URL 来“发现”REST 服务器上的每个资源?我不能只发布一个文档,上面写着“如果您需要获取所有蓝色小部件,请使用 URL '/widgets;color=blue'?
  • 是的,正如达雷尔所说。在某种意义上你可以大致这样想:在运行时以机器可读的形式(媒体类型)提供你心中的文档,并让客户端对其做出反应。一月
  • 您能否为以下说法提供引用或辩护:“特定的 URI 模式与您的应用程序将如何 RESTful 的问题正交”?
  • 我想反驳这种说法:“特定的 URI 模式与你的应用程序将如何 RESTful 的问题是正交的。”根据 p。在 Richardson 和 Ruby 的 233 个 RESTful Web 服务中,构建 URI 模式以匹配他们的“面向资源的架构”(ROA)有更好和更差的方法。总而言之:(1) 使 URI 代表资源(例如名词),(2) 使 URI 可由客户端构造,(3) 使用斜线从一般到特定,(4) 在顺序很重要时使用逗号,(5) 使用不使用分号时使用分号,并且 (6) 将查询变量用于算法。
  • FWIW,我同意资源可发现性确实很重要。我很高兴杰提出了它,因为它有时会被忽视。然而,这只是构建良好 RESTful API 的一部分——构建良好的 URI 也是必不可少的。
【解决方案2】:

我建议您使用此 URL 结构:

/appointments;user_id=1234;date=2010-02-22

为什么?我选择了/appointments,因为它简单明了。 (如果您有不止一种约会,请在 cmets 中告诉我,我可以调整答案。)我选择分号是因为它们不暗示 user_id 和 date 之间的层次结构。

还有一点,您没有理由将自己限制在一个 URL 上。拥有多个引用同一资源的 URL 结构就很好。所以你也可以使用:

/users/1234/appointments;date=2010-02-22

返回相似的结果。

也就是说,我不建议使用/dates/2010-02-22/appointments;user_id=1234。为什么?我不认为,在实践中,/dates 指的是资源。日期是约会的一个属性,但它本身不是名词(即它不是一流的东西)。

【讨论】:

  • 我认为 /appointments/user_id=1234;date=2010-02-22 稍微好一点,因为 /appointments/ 确实定义了层次结构中的一个点。
【解决方案3】:

我可以理解大卫詹姆斯的回答。
你的 URI 的格式可以像他建议的那样:

/appointments;user_id=1234;date=2010-02-22

和/或

/users/1234/appointments;date=2010-02-22

同时仍保持资源 URI 的可发现性(在运行时)(如 Jan Algermissen 建议的那样)。

【讨论】:

    猜你喜欢
    • 2016-11-26
    • 1970-01-01
    • 2020-03-22
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多