【问题标题】:Identifying collection subsets with RESTful URLs使用 RESTful URL 识别集合子集
【发布时间】:2012-11-28 18:55:41
【问题描述】:

假设我想获取我的公司在缅因州拥有的所有商店的列表。从概念上讲,这个请求可以被视为

/stores?state=Maine (All stores such that the state of the store is Maine)

/states/Maine/stores (All of Maine's stores)

哪个更 RESTful,为什么?根据我的理解,两者似乎都有各自的优缺点。

编辑:

我的原始示例存在的问题是,将商店作为状态的子资源可能没有直观意义,所以这里有另一个更详细的示例:假设我可以通过 ISBN 或按标题来识别每个作者的全局书籍(假设没有作者姓名他们自己的两本书一样)。因此,在此方案下,/books/0-525-94892-9/authors/Ayn_Rand/books/Atlas Shrugged 将引用同一本书。所以如果我想要 Ayn Rand 的所有书,我会GET /books?author=Ayn_Rand 还是GET /authors/Ayn_Rand/books

【问题讨论】:

  • 考虑到州名是独一无二的:)

标签: rest


【解决方案1】:
哪个更 RESTful,为什么?

两者都是 RESTful 的(尽管从技术上讲,REST URI 是不透明的,所以没关系)。哪个最适合您的用例取决于您的资源层次结构。

在您的书籍示例中,我将使用 ISBN,因为它是该书在其他地方使用的规范标识符。可能还有其他书籍称为“Atlas Shrugged”,可能还有其他作者称为“Ayn Rand”,或者同一作品的衍生版本可能会更改名称,或列出第二位作者,如果经过充分编辑。您需要提供至少两个数据,{author-name, book-name} 甚至可能是 {publication-year} 来唯一标识这本书。使用 ISBN 编号,您只需使用一个数据来识别图书。

/authors/{author-name}/books/{book-name} 的请求可能会返回302 Found 响应或更好的响应,返回带有/books/{isbn} 标题的Content-Location 的书,并在响应中使用rel="canonnical self" 链接指向ISBN URI资源。

编辑
我将提供一个来自我自己的 API 的示例:
我们有jobscontactssites。都是顶级资源。站点代表具有地址的物理位置。联系人通常代表公司,但有时是个人或学校等组织。一个站点有一个owner,它是一个联系人。当你去那个地址时,所有者就是标志上的名字。作业是顶级资源。作业有clientsitesite_owner。作业的客户是联系人(并非所有联系人都是客户),作业的 site_owner 是作业时站点的所有者,因为站点的所有者可能会随着时间的推移而改变,因为前提易手等等。我们有时也为不是网站所有者的客户做工作(即分包商工作)。无论客户是谁,当时谁拥有建筑物等,我们都需要保留在网站上完成的所有工作的历史记录。
因此,可以通过几个 URI,/contacts/{id}/sites/{id}/jobs/sites/{id}/jobs?client={id}/contacts/{id}/jobs?site={id} 访问特定客户在站点上完成的工作的工作列表,但实际上它们只是工作列表上的过滤器,完全等同于/jobs?client={id}&site={id} 确实所有的 URI 都是有效的,并最终到达同一个 PHP 文件并将相同的变量设置为相同的值并运行相同的查询,有些只是采取更迂回的路线并进行更多的 include 调用。 我允许所有这些不同 URI 的原因只是因为它允许我的用户在他们的导航层次结构中“上升”一两个级别(变量“面包屑”取决于到达列表所采用的路径; 这会稍微改变返回的表示形式),并且由于数据集是实时的,对于您可能正在查看的内容具有高度动态性,因此 HTML 结果是不可缓存的,因此不重用规范 URI 的权衡提供了更多好处而不是缺点。

所有的收获:

  • 为您的资源使用一个唯一标识符,或者如果您的资源本身没有一个唯一标识符(例如 ISBN),则创建一个 (id)

  • 您选择的 URI 与您的 API 的 RESTful 程度无关

【讨论】:

    【解决方案2】:

    除非/states/states/Maine 也是您系统中的资源,否则我将使用第一个示例。

    【讨论】:

    • 是的,states 是一个糟糕的例子。我已经更新了问题以使用更好的问题(作者和书籍),如果作者和书籍都是一流的资源,有什么建议吗?
    【解决方案3】:

    在你给出的两个例子中(州/商店和作者/书籍),我会使用后一种方案。

    它允许您以直观的方式公开各种不同的资源。 URI 明确了您期望哪些资源,并将使用中的约束表示为“路径”,而不是一堆 ?key=value&foo=bar&so=on...

    请允许我解释...

    /authors/
    

    将返回所有作者资源的列表。

    /authors/Ayn_Rand/
    

    将返回 Ayn Rand 资源,其中可能包含与 Rand 女士本人有关的信息。

    /authors/Ayn_Rand/books
    

    将返回 Ayn Rand 的书籍列表。这可能看起来像一个“简单”的书籍列表:

    [
    {
        title: 'Atlas Shrugged',
        genre: 'Fiction'
        slug: 'atlas_shrugged'
    },
    {
        title: 'The Fountainhead',
        genre: 'Fiction',
        slug: 'the_fountainhead'
    },
    {
        title: 'Capitalism: The Unknown Ideal',
        genre: 'Non-fiction',
        slug: 'capitalism_the_unknown_ideal'
    }
    ]
    

    您可能还希望使用 Hypermedia 来严格按照 ISBN 引用书籍:

    ...
    {
        title: 'Atlas Shrugged',
        genre: 'Fiction',
        location: '/books/0-525-94892-9'
    },
    ...
    

    【讨论】:

      猜你喜欢
      • 2011-12-12
      • 2013-01-20
      • 1970-01-01
      • 2016-04-12
      • 2018-04-18
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多