假设我有一个网站,用户可以上传并展示他们的照片。该用户的单张图片的RESTful网址如下所示:
http://api.gallery.com/users/{user-id}/images/{image-id}
但是image-id本身已经是唯一的了,所以这个url已经足够好了它:
http://api.gallery.com/images/{image-id}
从REST的角度来看,第一个是有利的,但是我应该验证,这个图像真的来自这个用户,因为有人可能会改变网址,将用户ID更改为其他人的。在后一种情况下,我不需要添加此检查,这意味着更少的处理时间。
在这种情况下,RESTful仍然是首选吗?
答案 0 :(得分:8)
简而言之,两者都是首选;两者都可以返回相同的“事物”,但“背景”是不同的。
我们来看看您的网址:
/users
:所有用户/users/1
:用户#1 /users/1/images
:所有用户#1的图片/users/1/images/1
:用户#1的图片#1 以上所有网址都围绕着“用户”资源。它是“所有用户”,“用户”,“用户的图像”等。
/images
:所有图片/images/1
:image#1 以上所有网址均围绕“图片”资源展开。它是“所有图像”或“图像”。
现在,从表面上看,这种区别可能看起来相对较小,但在构建API时,差异会对数据的消耗方式产生很大影响。
例如,假设您想要获取所有用户#1图像的列表,这是首选?
/users/1/images
或
/images?where=user.id eq 1
第一个代表正是我们想要的,更受约束,更容易理解,但是,这并不意味着我们不应该也支持第二种形式,因为查询的能力可以是很有用。
现在,如果你想获得一个图像列表及其相关用户呢?
/users/???
或
/images?include=user
在这种情况下,第一个网址根本没有多大意义,因为我们正在尝试获取图片列表,而不是用户,而第二个网址代表正是我们想要的。
现在,关于安全性,理想情况下应该以对消费者完全透明的方式进行。消费者应该能够说“我想要所有图像”。并且只接收他们可以访问的所有图像。如果他们尝试访问他们无权访问的特定资源,则应返回适当的HTTP错误代码。
答案 1 :(得分:1)
我认为第二种是因为你陈述的原因而更加RESTful。 URL是层次结构。 user-id实际上并不是图像标识的一部分,那么为什么要将它作为标识符的一部分呢?
制作/ users / {user-id} / images资源,返回表单/ images / {image-id}中的网址列表,以列出用户上传的图片,并且您可以充分利用这两种资源世界。
答案 2 :(得分:1)
我认为这一切都取决于语义和意图。您似乎在谈论受保护的资源,而不是公开的资源。在这种情况下,当使用更详细的格式时,您的通信更明确,并且具有最少的惊喜:
http://api.gallery.com/users/{user-id}/images/{image-id}
如果它是公共资源,那么它只能通过image-id识别,然后更短的格式会更符合逻辑:
http://api.gallery.com/images/{image-id}