Api 通过辅助(秘密)ID检索资源的最佳(RESTful)方法是什么?

Api 通过辅助(秘密)ID检索资源的最佳(RESTful)方法是什么?,api,rest,uri,api-design,Api,Rest,Uri,Api Design,我正在开发一个帐户邀请的API,其中一个用户创建一个邀请另一个用户加入平台,并具有一些特定的权限集。邀请本身将是一封众所周知的电子邮件,其中包含一个带有随机密钥的链接,用于接受邀请,类似于我们通常看到的密码重置和帐户确认流程的实现方式 与许多其他API一样,此API将具有常规CRUD操作,例如POST/invests/、GET/invests/{id}、DELETE/invests/{id}等,基于invite实体的实际id并实现常规授权方案。但我们还需要一种通过次要ID(链接中使用的秘密标识符

我正在开发一个帐户邀请的API,其中一个用户创建一个邀请另一个用户加入平台,并具有一些特定的权限集。邀请本身将是一封众所周知的电子邮件,其中包含一个带有随机密钥的链接,用于接受邀请,类似于我们通常看到的密码重置和帐户确认流程的实现方式

与许多其他API一样,此API将具有常规CRUD操作,例如POST
/invests/
、GET
/invests/{id}
、DELETE
/invests/{id}
等,基于invite实体的实际id并实现常规授权方案。但我们还需要一种通过次要ID(链接中使用的秘密标识符)检索invite的方法

可以考虑只使用秘密作为邀请的主要标识符,但这将是有问题的。因为知道秘密意味着允许应用邀请,所以秘密本身不应该(总是)被其他CRUD调用暴露;获取
/invests/
的响应通常不包含机密,这使得对邀请执行任何其他操作(如删除)都有问题

关于如何通过一个以上的标识符引用资源,已经有一些很好的问题,比如它所指向的其他几个标识符。通常,它们归结为:

  • 建议解决方案,如通过主id引用的
    /foos/{id}
    ,以及通过另一个字段引用的
    /foos/field/{value}
    ,在这种情况下,这是秘密。然而,我觉得这使得URI结构变得模棱两可,因为
    /foos/field/{value}
    也可以被理解为引用ID为'field'的foo的{value}'字段。由于ID通常是随机生成的,因此资源中的ID和实际字段名之间甚至可能发生冲突
  • 声明应该正好有1个URI引用1个资源,这意味着1个主标识符,并建议通过主标识符以外的任何内容引用资源应该表示为应该返回集合的筛选器查询。因此URI将变成
    /invests/?secret={secret}
    。然而,这并不“感觉正确”,因为秘密实际上只涉及一种资源。此外,这个“秘密”字段本身甚至可能不会在资源表示中公开,这让人觉得可以对其进行“过滤”有点奇怪
人们还经常指出,实际上不需要通过一个以上的唯一标识符来引用实体。但是,这样的用例将如何实现呢


在过去,我通过使用过滤器模式解决了类似的情况,但由于我不断遇到这种情况,我真的很好奇是否有更好的解决方案。

我最终想到的是定义一个新的集合“authLinks”,简称“authLinks”。“机密”是此集合中实体的主要标识符。这些实体有一个“resource”字段,该字段是指向此authLink公开的资源(在本例中为invite)的链接。从API检索此类“authLink”时,服务器将使用其自身的内部凭据检索链接资源,并将其作为“计算”字段resolvedResource包含在响应中

那么,交互将是什么样子的:

POST `/authLinks/supserSecretSecret` {"resource": "/invites/someId"} (with appropriate credentials)
> `{"id": "supserSecretSecret", "resource": "/invites/someId", "resolvedResource": {"id": "someId", ...}}`

GET `/authLinks/supserSecretSecret` (without credentials)
> `{"id": "supserSecretSecret", "type": "invite", "resource": "/invites/someId", "resolvedResource": {"id": "someId", ...}}`
系统组件和管理员可以使用适当的创建、更新和删除许可方案,对新资源或现有资源(如邀请或任何其他类型)的此类AuthLink进行CRUD。阅读不需要任何权限

在某些情况下,实现一次读取机制可能是合适的。尽管我们应该问问自己,在这种情况下,net GET是否是检索数据的适当方法(否),但绝对不要忘记设置适当的头以防止缓存

在我的情况下,这以一种通用的方式很好地解决了这个问题,即对于任何需要通过共享秘密链接访问的资源