我正在构建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的更好解释。上面没有列出其他选项吗?
答案 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上,则有几种不同的方法可以告诉客户端它们实际上是同一件事:
308
)到另一个。canonical
链接指示存在一个规范的位置来获取信息。Content-Location
标头执行相同的操作。答案 1 :(得分:0)
如果您不需要公开ID形式http://myserver/api/account/123,并且每个帐户都有唯一的助记符,则将http://myserver/api/account/的形式当您使用助记符作为标识符时将是完全有效的。 REST并没有规定数据库的主键必须是服务公开的标识符。可以唯一标识资源的任何东西。