假设我想获得我公司在缅因州拥有的所有商店的清单。从概念上讲,此请求可以视为
/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
?
答案 0 :(得分:1)
除非/states
和/states/Maine
也是您系统中的资源,否则我将使用第一个示例。
答案 1 :(得分: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'
},
...
答案 2 :(得分: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
,contacts
和sites
。所有这些都是顶级资源。站点代表带有地址的物理位置。联系人通常代表公司,但有时候是个人或像学校这样的组织。网站有一个owner
是一个联系人。当您前往该地址时,所有者是标志上的名称。工作是顶级资源。工作有client
,site
和site_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只是因为它允许我的用户在其导航层次结构中“升级”一级或两级(变量“breadcrumbs”取决于到达列表所采用的路径;它稍微改变了返回的表示),并且因为数据集是实时的,对于您可能正在查看的事物是高度动态的,因此HTML结果是无法访问的,因此不重复使用规范URI的权衡提供了更多的好处而不是低谷。
所有这一切的收获:
为您的资源使用单个唯一标识符,或者如果您的资源本身并非一个(例如ISBN),则创建一个(id
)
您选择的URI与您的API的RESTful