自然键和 RESTful URL
Posted
技术标签:
【中文标题】自然键和 RESTful URL【英文标题】:Natural keys and RESTful URLs 【发布时间】:2014-07-10 04:00:59 【问题描述】:我正在设计一个 RESTful API,它对所有资源使用数字主键。然而,一种类型的资源有一个方便的自然键,我希望能够将其用作指定单个资源的可选方式。为了一致性起见,所有资源都可以通过它们的主键访问。
就目前而言,我可以这样做(假设23
是主键):
mysite.com/api/v0/sites/23/
但是,我想知道是否有一种惯用方法来指定资源的备用自然键。
到目前为止,我正在考虑做这样的事情:
mysite.com/api/v0/sites/?domain-name=someothersite.com/
因此,单个站点资源可以通过其主键和自然键(其域名)访问。我主要关心的是以惯用的方式执行此操作,因为我想让 API 尽可能简单易用。
【问题讨论】:
很好,我的意思是我从未在示例中考虑过v0
,但这是有道理的。 :-)
【参考方案1】:
在您的特定情况下,主键(整数)总是可以很容易地与域名(包括句点的字符串)区分开来。允许两者在 URL 的同一位置似乎完全有效(且直观):
mysite.com/api/v0/sites/23
mysite.com/api/v0/sites/someothersite.com
记录它也很简单,因为每个都是站点的唯一标识符:
mysite.com/api/v0/sites/id
id: primary key or fully-qualified domain name
【讨论】:
【参考方案2】:我也一直在努力寻找这个问题的令人满意的答案。我已经开始按照 Mike Dunker 的建议实现相同的功能,但最终遇到了一些无法区分代理键和自然键的资源。就在那时,我意识到我宁愿有一个统一的方法来解决这个问题,而不是混合不同的方式——就像你说的那样,一些惯用的方法。
http://soabits.blogspot.de/2013/10/url-structures-and-hyper-media-for-web.html 描述了我发现的另一种方法(在“自然键、代理键、URL 别名和资源重复”下)。
想法是将两种可能的密钥方案之一定义为规范的一种,并通过向 URI 添加一个段并使用 HTTP 303(参见其他)重定向到规范的 URI 来实现另一种。
因此,在您的示例中,您可以将 mysite.com/api/v0/sites/23/
作为规范 ID,mysite.com/api/v0/sites/domain-name/someothersite.com/
将回复 HTTP 303 和包含 mysite.com/api/v0/sites/23/
的位置标头(或相反)。由于http://www.w3.org/TR/webarch/#uri-aliases 中提到的原因,使用 URI 别名的重定向而不是“复制”相同的资源很有用。
我也没有采用此解决方案的原因是额外的 HTTP 往返,这在我们的项目设置中可能过于昂贵。
【讨论】:
【参考方案3】:通过使用key
参数来表示资源ID 所指的自然键,这是一个比Mike's 更强大的想法:
mysite.com/api/v0/sites/23
和
mysite.com/api/v0/sites/someothersite.com?key=domain-name
在您的控制器中,您可以验证键参数是否只是您的自然键,而不是查询表元信息以获取唯一索引。如果您不喜欢污染查询字符串,也可以使用 HTTP 标头。
【讨论】:
【参考方案4】:请注意,ORM 实体或域实体不是资源。这些实体和资源之间可以存在映射。资源是一个应用接口的概念,你可以用资源来描述你的服务的接口以及对这些资源的操作。
因此,您的主键不标识资源,而是标识实体。资源由 URI 标识。 URI 不是唯一标识符,因此您可以使用多个 URI 来标识单个资源。
马克是对的,你可以使用类似的URI模板
mysite.com/api/v0/sites/id
mysite.com/api/v0/sites/hostname
如果您的路由框架支持按类型区分路由。因此,如果类型是数字,则 id 路由将运行,如果类型与主机名正则表达式模式匹配,则主机名路由将运行。否则,您可以合并 2 条路线并使用您的代码手动处理它们之间的差异。
【讨论】:
以上是关于自然键和 RESTful URL的主要内容,如果未能解决你的问题,请参考以下文章
选择哪一个:ASP.NET MVC 还是 RESTful WCF?