通过不同的标识符获取REST时,对REST的正确解释是什么?

时间:2018-11-17 16:07:44

标签: rest

我正在构建REST API,我想对URI进行最纯粹的解释,以便使用多个唯一标识符访问资源。例如,我的基础POCO如下所示:

public class Account
{
  int AccountId { get; set; }
  string Mnemonic { get; set; }
  string LegacyId { get; set; }
  string Name { get; set; }
}

主键是AccountId,主要用作内部标识符(也由UX使用),但助记符也是唯一的,供人类使用(以及从外部系统导入)。可能还有旧系统标识符挂在较旧的系统上。通过主键访问元素时,毫无疑问,URI应该是:

GET: http://myserver/api/account/123

但是,我们应该如何使用其他唯一标识符访问记录?我看过使用的查询表单:

GET: http://myserver/api/account?query=EmergingMarkets

这让我感到天生就是非REST的,因为它看起来像是一个动作而不是参考。我一直在使用这种形式:

GET: http://myserver/api/account/mnemonic/EmergingMarkets
GET: http://myserver/api/account/legacyId/EM10

对纯REST的更好解释。上面没有列出其他选项吗?

2 个答案:

答案 0 :(得分:1)

我将从评论中选出第二位罗马人。对REST有几种不同的解释,但是当具体谈论“最纯正的”时,通常我认为您需要按照原始定义朝HATEOAS /超媒体服务的方向发展。

该定义非常宽松,因为它没有说明与HTTP绑定的外观的 exact 协定,但通常认为应该通过以下链接来发现URI,带外信息。客户端不必真正对URI模式进行硬编码,并且有多种机制专门用于搜索(例如HAL模板链接)。

因此,这些段落通过字母回答您的问题,现在让我们回答您可能想知道的内容:从API设计的角度来看,什么是针对您的特定问题的优雅URI设计,这是可预见的和明智的。

我要问的第一件事是,为什么您完全需要'id'表格?

 http://myserver/api/account/123

123有点丑陋,如果您不直接访问数据库,那是毫无意义的。听起来好像您的“助记符”是1:1的关系,为什么不完全放弃数字形式而总是使用自然键。

它看起来好多了,并且一口气消除了重复问题。如果这不是一个选择(也许不是每个实体都有一个“助记符”),并且您必须有2个位置来访问资源,我认为:

?query=x向我建议,这是一个搜索,可以将0返回n资源作为集合。我个人会避免使用单一的独特资源。这不是 action action 仍为GET,因此对于搜索来说应该没问题。

这留下了/api/account/mnemonic/EmergingMarkets,尽管我个人会把它放在与/api/account不同的名称空间中。由于api/account看起来像一个具有所有帐户作为成员的集合,因此api/account/mnemomic可能看起来就像另一个帐户。我的感觉更多地表明存在两种不同的结构,例如:

/api/account/id/123
/api/account/mnenomic/EmergingMarkets

或者:

/api/account/123
/api/account-by-mnenomic/EmergingMarkets

无论如何,我的答案的第一部分是您所询问的内容和基于事实的答案,第二部分是我想要的答案,但显然完全是基于意见的。再问5个人,您至少会得到一些不同的答案。

奖金

如果您确实有2个相同的资源托管在2个不同的url上,则有几种不同的方法可以告诉客户端它们实际上是同一件事:

  1. 让1进行永久重定向(308)到另一个。
  2. 同时为您的文档和文档提供服务,并使用canonical链接指示存在一个规范的位置来获取信息。
  3. 使用Content-Location标头执行相同的操作。

答案 1 :(得分:0)

如果您不需要公开ID形式http://myserver/api/account/123,并且每个帐户都有唯一的助记符,则将http://myserver/api/account/的形式当您使用助记符作为标识符时将是完全有效的。 REST并没有规定数据库的主键必须是服务公开的标识符。可以唯一标识资源的任何东西。