用于与用户相关的列表的REST API设计

时间:2014-05-28 04:31:16

标签: api rest

我有点惊讶我没有在更多的REST讨论中看到这一点,但我正在讨论如何根据用户是谁或他们有权查看的内容,最好地向用户提供一系列内容

例如,假设我们有一个书店的API。我可能有一个/books的资源网址,它会列出所有图书。但是,如果我的应用程序逻辑是某些书籍可供匿名用户查看,但其他书籍只能登录,那么我更不确定最佳方法。

显然,我可以通过编程方式根据用户的身份(从他们的API密钥或我正在使用的任何信誉中收集)进行过滤,但我觉得从REST设计的角度来看,这有点“关闭”。

感觉更有权拥有两个端点;假设一个用于/books/public,一个用于/books/restricted,我们可以说如果用户没有登录则后者返回401.足够简单。

但是,如果相关书籍只是用户已阅读或已购买的书籍列表或与用户有其他关系,那么该模式会有所突破。在这种情况下,我已经看到了一些类似于/my/books的API,但由于/my/books本身不是一个唯一的网址,它会再次感觉不到,它会再次(基于)更改标头值(API密钥等)。

这让我觉得可能“最好”的方法是做/books/users/1235/users/1234/books之类的东西来获取“属于”用户1234的书籍,如果有人则返回401未经过身份验证尝试访问该URL,如果经过身份验证但未获得查看该资源的权限,则尝试403.

我想这是我的主要问题的背景知识:当资源数据依赖于用户身份时,REST API URL设计的最佳实践是什么?

2 个答案:

答案 0 :(得分:2)

休息不是标准,所以在技术上没有正确或错误的方法来完成你所追求的目标。话虽如此,我会给你我的意见。

我建议您只使用/books,除非对服务或用户有非常具体的需求,以查看哪些服务或用户是唯一的,哪些是公开的。在这种情况下,我建议做三个。基于用户权限在/books端点上可能有更多或更少内容的事实不会改变意图,它会增强它。

  

但是,如果相关书籍只是用户已阅读或已购买的书籍列表或与用户有其他关系,那么该模式会有所突破。在这种情况下,我已经看到了一些像/ my / books这样的API,但是(再次)感觉不对,因为/ my / books本身不是一个唯一的URL,它会根据(再次)在标题上更改值(API密钥等)。

我认为如果内容是私有的,提供/my/books端点是理想的。如果您的阅读列表是私有的并且特定于您的帐户,那么拥有没有该列表的端点会显着降低显着降低通过URL泄露用户识别信息的风险。

如果可以共享阅读列表,那么您可能希望有一个离散的动作。如果用户希望共享他们的阅读列表或其中的子集,他们将组成该列表,并且将专门为其创建新的端点,如/book-lists/xxxx-xxxx-xxxx。如果您的用户的阅读列表本质上是公开的,那么/my/books只会重定向到/booklists/xxxx-xxxx-xxxx

  
    

这让我觉得可能“最好”的做法是做/ books / users / 1235或/ users / 1234 / books之类的东西来获取“属于”用户1234的书籍,然后返回401如果未经过身份验证的人尝试访问该URL,或者如果他们经过身份验证但未获得查看该资源的权限,则为403.

  

我不确定您是否通过某种形式的凭证来引用阅读列表或过滤结果的第一个概念。

从书的角度来看,

/books/users/1234会建议与用户建立关联。这更适用于作者或出版商,除了上述示例之外,实际上与书籍有关联的人。对我来说,同样的逻辑联系适用于/users/3493/books但在较小程度上适用。

我认为,作为一种通用方法,如果您希望共享公共链接,则应该将这两种方法都删除。你可能会制造一个非常复杂的结构,最终可能会让人们感到困惑,为什么他们的朋友看不到小说列表,因为她发送了她的搜索结果,其网址已经“个性化”并因此受到保护。

答案 1 :(得分:1)

  

显然,我可以通过编程方式根据身份进行过滤   用户(从他们的API密钥或我正在使用的任何信誉中收集)但是   从REST设计的角度来看,我觉得这有点“关闭”。

不,它没有关闭,因为凭据是每个请求的一部分,响应可能依赖于请求参数......

网址取决于您是否要与他人共享个人数据:

如果你想分享网址

  • /users/{userId}/favouriteBooks/
  • /books/favouriteOf:{userId}/

如果您不想分享网址

  • /books/favourite/

请注意,只要您的服务采用HATEOAS原则,您始终可以更改网址结构...