自然键和RESTful URL

自然键和RESTful URL,rest,restful-url,restful-architecture,api-design,Rest,Restful Url,Restful Architecture,Api Design,我正在设计一个RESTful API,它对所有资源使用数字主键。但是,有一种资源类型有一个方便的自然键,我希望能够使用它作为指定单个资源的可选方式。为了一致性起见,所有资源都可以通过主键访问 目前,我可以这样做(假设23是主键): 但是,我想知道是否有一种惯用的方法来指定资源的备用自然键 到目前为止,我正在考虑这样做: mysite.com/api/v0/sites/?domain-name=someothersite.com/ 因此,单个站点资源可以通过其主键和自然键(其域名)进行访问。我主

我正在设计一个RESTful API,它对所有资源使用数字主键。但是,有一种资源类型有一个方便的自然键,我希望能够使用它作为指定单个资源的可选方式。为了一致性起见,所有资源都可以通过主键访问

目前,我可以这样做(假设
23
是主键):

但是,我想知道是否有一种惯用的方法来指定资源的备用自然键

到目前为止,我正在考虑这样做:

mysite.com/api/v0/sites/?domain-name=someothersite.com/

因此,单个站点资源可以通过其主键和自然键(其域名)进行访问。我主要关心的是如何以一种简洁、惯用的方式来实现这一点,因为我希望使API尽可能简单易用

在您的特定情况下,主键(整数)总是可以很容易地与域名(包含句点的字符串)区分开来。允许两者位于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

对于这个问题,我也很难找到令人满意的答案。我已经开始实现Mike Dunker建议的相同功能,但最终遇到了一些无法区分代理密钥和自然密钥的资源。就在那时,我意识到我更希望有一个统一的方法来解决这个问题,而不是混合不同的方法——就像你说的,一些惯用的方法

我发现的另一种方法在中进行了描述(在“自然键、代理键、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/
的位置头进行回复(反之亦然)。使用URI别名重定向而不是“复制”同一资源非常有用,原因如下所示


我没有使用此解决方案的原因也是额外的HTTP往返,这在我们的项目设置中可能过于昂贵。

这里有一个比使用
参数来表示资源ID所指的自然键更可靠的想法:

mysite.com/api/v0/sites/23


在控制器中,您可以验证key param是否仅为您的自然键,而不是说查询表meta info以获得唯一索引。如果您不想污染查询字符串,还可以使用HTTP头。

请注意,ORM实体或域实体不是资源。这些实体和资源之间可能存在映射。资源是一个应用程序接口概念,您可以描述服务与资源的接口以及对这些资源的操作

因此,您的主键不标识资源,而是标识实体。资源由URI标识。URI不是唯一标识符,因此可以使用多个URI来标识单个资源

Mark是对的,您可以使用类似的URI模板

mysite.com/api/v0/sites/{id}
mysite.com/api/v0/sites/{hostname}

如果路由框架支持按类型区分路由。因此,如果类型为数字,则id路由将运行,如果类型与主机名正则表达式模式匹配,则主机名路由将运行。否则,您可以合并这两条路由,并使用您的代码手动处理它们之间的差异。

Nice,我的意思是我从未在示例中想到过
v0
,但这很有意义。:-)
mysite.com/api/v0/sites/someothersite.com?key=domain-name
mysite.com/api/v0/sites/{id}
mysite.com/api/v0/sites/{hostname}