1

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

/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

4

3 回答 3

1

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

于 2012-11-28T19:04:59.853 回答
1

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

它允许您以直观的方式公开各种不同的资源。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'
}
]

您可能还希望使用超媒体来严格按其 ISBN 引用书籍:

...
{
    title: 'Atlas Shrugged',
    genre: 'Fiction',
    location: '/books/0-525-94892-9'
},
...
于 2012-11-29T10:57:54.553 回答
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响应或更好,返回带有Content-Location标题的书/books/{isbn}并在响应中使用rel="canonnical self"链接指向资源的 ISBN URI。

编辑
我将从我自己的 API 中提供一个示例:
我们有jobs,contactssites. 都是顶级资源。站点代表具有地址的物理位置。联系人通常代表公司,但有时是个人或学校等组织。一个站点有owner一个联系人。当你去那个地址时,所有者就是标志上的名字。作业是顶级资源。作业有 a client、 asite和 asite_owner. 作业的客户是联系人(并非所有联系人都是客户),作业的 site_owner 是作业时站点的所有者,因为站点的所有者可能会随着时间的推移而改变,因为前提易手等等。我们有时也会为非网站所有者的客户(即分包商工作)做工作。我们需要保留在站点上完成的所有工作的历史记录,无论客户是谁,当时谁拥有建筑物等。
因此,可以通过以下几种方式访问​​在站点上为特定客户完成的工作的工作清单URIs, /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 的权衡提供了比不利方面更多的好处。

从这一切中得出的结论是:

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

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

于 2012-11-29T11:32:03.113 回答