通过代理ID或业务ID在资源上获取GET的REST方法

时间:2012-01-06 22:39:18

标签: java web-services rest jax-rs

我们有一些实体既有唯一的业务ID(例如“my-unique-name”),也有内部UUID(例如aa54-342-dffdf-55445-effab)。什么是提供可以使用任一方法返回资源的REST URI的好方法。

方法1 - 有两个资源URL(丑陋!!!):

  

/富逐ID /我的唯一的名称

     

/富逐UUID / aa54-342-dffdf-55445-effab

方法2 - 始终使用查询参数(即使它返回单个项目......似乎是非休息)

  

/富?ID =我的唯一的名称

     

/富?UUID = aa54-342-dffdf-55445-effab

方法3 - 让网络服务弄清楚{id}是否是UUID(这可能容易出错,但在所有likihood中都可以正常工作......

方法4 - 使用UUID,允许业务ID作为查询参数(不知道这是否有效)

  

/富?ID =我的唯一的名称

     

/富/ aa54-342-dffdf-55445-effab

任何想法都表示赞赏。

6 个答案:

答案 0 :(得分:6)

我会使用类似于选项4的东西。使用路径段中的UUID作为单个资源URL。使用备用网址作为一种搜索网址

e.g。

GET /foo?name=my-unique-name

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

您不希望有两个URL都返回具有相同资源的200。这会导致缓存污染 现在,您可以自由地将GET“搜索样式”URL用于其他类型的搜索。

GET /foo?account=other-unique-value

303 See Other
Location: http://example.org/foo/aa54-342-dffdf-55445-effab

或者你甚至可以搜索非独特的东西。

GET /foo?country=a-non-unique-value

200 OK
Content-Type: application/vnd.hal+xml

<resource href="http://example.org/foo?country=a-non-unique-value">
   <resource rel="urn:acme:foo" href="http://example.org/foo/aa54-342-dffdf-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ba54-299-weras-55445-effab"/>
   <resource rel="urn:acme:foo" href="http://example.org/foo/ca54-743-werre-23434-effab"/>
<resource>

答案 1 :(得分:5)

选择一个作为规范,307将另一个重定向到它。如果不这样做,则会冒两个URI返回不同数据的风险,因为它们已在不同的时间或生命周期进行缓存。通过从一个重定向到另一个,您允许PUT,POST或DELETE请求使单个规范URI的缓存无效。使用307而不是302,以便“历史”客户端不会将POST更改为GET。我推荐方法1,让UUID重定向到商业ID只是因为它更漂亮。

答案 2 :(得分:3)

REST并不是关于优秀网址的全部内容。然而,在我看来,第一种方法并不是真正的REST,因为你指出了两个“资源”。

第二种方法是REST,但如果你不想拥有QS样式的URL,你可以这样做:

/foo/id-my-unique-name
/foo/uuid-aa54-342-dffdf-55445-effab

然后你可以使用正则表达式将其拆分。

就我而言,我喜欢最后一个因为网址很好。

答案 3 :(得分:1)

我会采用第二种方法。 Moslty因为从语义上讲,你想要通过“过滤”来获取名为foo的实体。 通过定义对其属性的约束,即id或uuid,可以明显地反映出这一点。

那就是说,REST不是关于URL。您正在谈论的方法通常被称为“不错的网址”。 REST是关于由公共操作(HTTP方法)和名称(URL)执行的资源表示的语义驱动操作。

您可以在Fielding dissertation上阅读有关REST的更多信息。

此外,如果您想要RESTful,那么每个实体都应该有唯一的URL。但正如菲尔丁自己指出的那样,没有人是RESTful。

答案 4 :(得分:1)

我正在开发具有休息调用的Android应用程序,我使用第二种方法, 其原因是休息独特的路径id更适合人类可读的格式 例如http://example.com/rest/news/2007/6显然代表2007年和6月的新闻。

答案 5 :(得分:0)

根据REST原则,每个 表示 都应该有唯一的URI。

具有业务密钥的那个也可能通过业务密钥引用相关实体,因此该表示与具有UUID的表示不同,UUID可能将UUID用于其相关实体。

/foo/my-unique-name -> link: /foo/parent-uniquename
/internal/foo/aa54-342-dffdf-55445-effab -> link: /internal/foo/parent-xxxyyyy