具有多个ID的资源的REST路径设计

具有多个ID的资源的REST路径设计,rest,Rest,我试图为一个新服务的REST路径定义API,其中我有设备,每个设备都有一个当前位置 需要一些背景知识才能理解问题: 这是关于将当前设备位置推送到中央服务器 位置更新有时在设备本身(GPS)上计算并从设备(智能手机)发送到服务器,但有时也通过外部服务(如WiFi定位系统)从该系统发送到服务器 每个设备都有一个智能手机知道的唯一id。WiFi定位系统无法知道该id,它只知道WiFi mac地址 每个设备都有几个位置更新接口(mac地址) 无论接口位置更新来自何处,所有位置数据都应链接到相同的唯一设

我试图为一个新服务的REST路径定义API,其中我有设备,每个设备都有一个当前位置

需要一些背景知识才能理解问题:

  • 这是关于将当前设备位置推送到中央服务器
  • 位置更新有时在设备本身(GPS)上计算并从设备(智能手机)发送到服务器,但有时也通过外部服务(如WiFi定位系统)从该系统发送到服务器
  • 每个设备都有一个智能手机知道的唯一id。WiFi定位系统无法知道该id,它只知道WiFi mac地址
  • 每个设备都有几个位置更新接口(mac地址)
  • 无论接口位置更新来自何处,所有位置数据都应链接到相同的唯一设备id
背景就到此为止。现在谈谈API设计。如上所述,我可能会在只有mac地址已知的情况下获得位置更新,并且我可能会在唯一设备id已知的情况下获得位置更新。在这两种情况下,我可以假设我得到的id是唯一的,理论上我可以说mac地址x属于设备y。实际上,这意味着我的位置REST API有一个非唯一索引:

例如,考虑到我有一个ID为“123”的设备,还有两个MAC地址“abc”和“XYZ”。通常,我的REST API路径会将位置分组到唯一设备下:

/devices/$id/location
现在的问题是存在多个(唯一)ID,但每个ID都与同一个设备相关

例如,这将通过智能手机的唯一设备id推送位置(我知道该唯一id,但不知道接口的mac地址):

这是一个只知道mac地址的外部系统使用mac地址作为密钥推动位置更新的地方:

PUT /devices/abc/location
PUT /devices/xyz/location
您可以假设,在内部,我可以将mac地址和唯一的设备ID与一个唯一的内部设备相关联。我可以使用mac地址和设备id更新并返回位置和设备信息

例如,以下使用唯一设备id或唯一mac的GET请求将返回相同的位置对象:

GET /devices/123/location
GET /devices/abc/location
GET /devices/xyz/location

但这是一种有效的REST设计吗?在这种设计中,我可以拥有指向同一资源的多条路径?我是否应该更改我的REST路径,以及如何更改?

考虑一下如何设计一个支持此行为的网站可能会很有用

您可以这样设计该协议:客户端加载一个已知的书签URI。在该页面的表示中有两个链接可用,一个用于知道mac地址的客户端,另一个用于知道标识符的客户端。客户将选择适当的链接进行跟踪。它返回的表示将是一个表单,为特定用例定制;表单的描述将指定所需的字段。客户机将填写已知字段(忽略任何未知字段,这些字段可能具有合理的默认值),然后提交表单。浏览器将使用标准处理规则为表单中指定的操作生成适当的HTTP请求

在这种情况下,我们感兴趣的是(有效地)根据我们拥有的信息查找我们想要的资源的URI,我们通常使用
GET
作为表单方法。这将向服务器发送一个查询,服务器可以从那里(可能通过重新定向)通信用于该设备的适当URI

一旦有了正确的URI可以使用,GET/PUT/POST/PATCH/DELETE应该可以像您预期的那样工作

这是一个有效的REST设计,我可以有多个路径到同一个资源

如果标识符不同,则资源也不同。当然,您可以拥有多个表示某个概念的资源(或者,换句话说,两个不同的资源可以共享一个语义映射)

对于您的特定情况,可能可以为通过id了解设备的客户端提供一个资源,为通过位置了解设备的客户端提供另一个资源。但是,在这两种情况下共享单个资源标识符可以简化服务器端缓存的过程

休息点的一部分:如果仔细定义媒体类型和关系,服务器应该能够在不中断任何客户端的情况下更改所使用的缓存策略(因为客户端只是在跟踪服务器提供的链接和提交表单)

GET /devices/123/location
GET /devices/abc/location
GET /devices/xyz/location