使用RESTful URL标识集合子集
假设我想得到缅因州我的公司拥有的所有商店的列表。从概念上讲,此请求可以被视为使用RESTful URL标识集合子集,rest,Rest,假设我想得到缅因州我的公司拥有的所有商店的列表。从概念上讲,此请求可以被视为 /stores?state=Maine (All stores such that the state of the store is Maine) 或 哪个更安静,为什么?从我的理解来看,两者似乎各有利弊 编辑: 我最初的示例有一个问题,即将存储作为状态的子资源可能没有直观的意义,因此这里有另一个更详细的示例:假设我可以通过ISBN全局识别书籍,或者通过标题识别每个作者(假设没有作者将自己的两本书命名为相同的名称)
/stores?state=Maine (All stores such that the state of the store is Maine)
或
哪个更安静,为什么?从我的理解来看,两者似乎各有利弊
编辑:
我最初的示例有一个问题,即将存储作为状态的子资源可能没有直观的意义,因此这里有另一个更详细的示例:假设我可以通过ISBN全局识别书籍,或者通过标题识别每个作者(假设没有作者将自己的两本书命名为相同的名称)。因此,在这个方案下,
/books/0-525-94892-9
和/authors/Ayn_Rand/books/Atlas shuggled
将引用同一本书。因此,如果我想要所有由Ayn Rand出版的书,我会GET/books?author=Ayn_Rand
还是GET/authors/Ayn_Rand/books
?除非/states
和/states/Maine
也是您系统中的资源,我会使用第一个示例。在您给出的两个示例中(州/商店和作者/书籍),我会采用后一种方案
它允许您以直观的方式公开各种不同的资源。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'
},
...
哪个更安静,为什么?
两者都是同样的RESTful(尽管从技术上讲,RESTURI是不透明的,所以这无关紧要)。哪个最适合您的用例取决于您的资源继承权
从您的图书示例中,我将使用ISBN,因为它是该图书的cannonical标识符,与其他地方使用的一样。可能还有其他的书叫《阿特拉斯耸耸肩》,也可能有其他的作者叫《艾恩·兰德》,或者同一作品的衍生版本可能会改变名字,或者列出第二作者,如果编辑充分的话。您需要提供至少两个数据,{author name,book name}
,甚至可能是{publication year}
,以唯一地标识图书。对于ISBN编号,您只能使用一个数据来识别图书
对/authors/{author name}/books/{book name}
的请求可能会返回302 Found
响应,或者更好,返回带有/books/{isbn}
标题的内容位置的图书,并在响应中使用rel=“canonical self”
链接指向资源的isbn URI
编辑
我将从自己的API中提供一个示例:
我们有工作
,联系人
和网站
。所有这些都是顶级资源。站点表示具有地址的物理位置。联系人通常代表一家公司,但有时是个人或学校等组织。站点有一个所有者
,这是一个联系人。当你去那个地址的时候,主人就是标志上的名字。工作是顶级资源。作业有一个客户端
、一个站点
和一个站点所有者
。作业的客户是一个联系人(并非所有联系人都是客户),作业的站点所有者是作业时站点的所有者,因为站点的所有者可能会随着时间的推移而变化,例如Premese易手等等。我们有时也为非现场业主的客户工作(即分包商工作)。我们需要保留现场所有工程的历史记录,无论客户是谁、当时谁拥有该建筑等。
因此,可以在多个URI下访问特定客户端在站点上完成的工作的作业列表,/contacts/{id}/sites/{id}/jobs
,/sites/{id}/jobs?client={id}
,/contacts/{id}/jobs?site={id}
,但实际上它们只是作业列表上的过滤器,完全等同于/jobs?client={id}&site={id}
事实上,所有URI都是有效的,最终都会访问同一个PHP文件,将相同的变量设置为相同的值,并运行相同的查询,有些URI只是走了一条更迂回的路线,执行了一些include
调用。
我允许所有这些不同URI的原因仅仅是因为它允许我的用户在他们的导航继承权中“上”一两级(根据到达列表的路径而定的变量“breadcrumbs”;这稍微改变了返回的表示),并且由于数据集是实时的,对于您可能看到的内容来说是高度动态的,因此HTML结果是不可缓存的,因此不重新使用cannonical URI的折衷方案提供了比负面效果更多的好处
从一切事物中带走的是:
- 为您的资源使用一个唯一的标识符,或者如果您的资源本身没有唯一的标识符(如ISBN),则创建一个(
id
)
- 您选择的URI与API的RESTful程度无关
考虑到各州的名字是独一无二的:)是的,从各方面考虑,各州都是一个糟糕的例子。我已经更新了这个问题,以使用更好的一个(作者和书籍),如果作者和书籍都是一流资源,有什么建议吗?
...
{
title: 'Atlas Shrugged',
genre: 'Fiction',
location: '/books/0-525-94892-9'
},
...