1

One issue about the restful service API designing. I'm not sure how is a proper way to do it. Please give me some suggestions.

My scenario is like this. I have a user resource and permission resource.

http://www.sample.com/rest/users
http://www.sample.com/rest/permissions

User can have multiple permission; one permission can be used for many users; it is many to many relationship.

Normally, we can say a permission belongs to a user, so we have an API like:

http://www.sample.com/rest/users/{userId}/permissions

When we want to build a relationship between the permission and an user, here are two options.

  1. we can first use POST: http://www.sample.com/rest/permissions with a permission body, then POST: http://www.sample.com/rest/users/{userId}/permissions with a set of permission ids. I'm not sure if there is any other rest APIs designing like this.

  2. we can use only one API like: http://www.sample.com/rest/users/{userId}/permissions with a permission object content. In this method, we do two things I descript in option 1. The downside is that we cannot never reuse the created permission, it looks like one user can have multiple permissions, but one permission only used by one user, which obey our first designing. But it is really simple to user.

If you have any experience on this topic, any suggestions are welcome.

4

3 回答 3

3

如果权限对象足够复杂以至于看起来像一个单独的实体(或者如果您需要在用户之间共享权限对象),我将使用单独的权限 URL。如果权限“对象”只是一个rwx字符串或类似的东西,那么不值得引入一个独立的实体。另一方面,如果权限对象更复杂(例如与文件夹列表关联的权限列表),则将其存储为单独的实体并为此使用单独的 URL 可能是有意义的。

于 2013-08-07T16:03:48.747 回答
2

另一种方法是将用户和权限视为分离的“空间”或资源。您应该能够使用CRUD单独管理它们。

创建用户

  • 发布:/用户/
  • 返回:{用户ID}

创建权限

  • 发布:/权限/
  • 返回:{permid}

然后来映射,你应该使用 PUT 代替,因为它不是创建新资源而是映射两个资源

将用户添加到权限空间

  • 放置:/permissions/users/{userId}/

或将用户添加到权限空间

  • PUT:/权限/用户/
  • 正文:{[userid1,userid2,...]}

向用户空间添加权限

  • 放置:/users/permissions/{permId}/

或向用户空间添加权限

  • PUT:/用户/权限
  • 正文:{[permid1,permid2,...]}
于 2013-08-10T02:47:41.550 回答
1

资源

首先,让我们谈谈您将拥有哪些“资源”和“收藏”。

  • /users一个很好的简单开始,/permissions每一个都是所有用户和所有权限的集合。
  • /users/{id}/permissions/{id},其中每一个分别是用户或权限的单个资源。
    • 用户可能有“姓名”、“注册日期”、“身份证”等字段。
    • 权限可能包含“名称”、“创建日期”、“ID”等字段。

到目前为止很好很简单。不管你从这里走到哪里,这两种类型的资源仍然作为独立的实体存在,一个用户可以没有权限,一个权限可以没有用户。但是现在我们需要将这些链接在一起吗?首先,让我们展示一个看似简单却让大多数人大吃一惊的概念......

/users/{id}/name可用于根据 ID 仅返回用户的名称。您不必支持这种行为,如果您这样做,那么您不应该直接将名称作为“用户”资源的一部分返回(您应该链接到这个特定的名称资源)。

这个概念也可以应用于权限。因此,我们还添加/users/{id}/permissions了 ,既可以作为您可以调用的资源,也可以作为您通过GET的资源中的“链接” (因此开始使用 html的超部分)。那么这会返回什么呢?它可能是这样的:GET/users/{id}

/permission/3
/permission/666
/permission/7

这些资源是否在用户“下方”,不。他们需要吗,不。那么,如果您GET是这些权限资源之一呢?

name=admin
id=666
created-date=12/3/45
users=/permission/666/users

最后一行,就像一个用户拥有一组权限一样,一个权限拥有一组拥有它的用户。(我想你可以弄清楚那会是什么样子)

创建资源

在第一部分中,我介绍了这两种类型的资源如何相互关联。但是,您的问题更多是关于如何创建这些资源。显然,您可以允许操作员(我会说操作员以避免与“用户”资源混淆)创建用户,同时定义他们应该拥有的权限:

{ "name" : "Frank",
  "permissions" : [
    ...
  ]
}

服务器将为您生成“id”和“sign-up-date”。权限列表可以允许使用“id”或“名称”,后者将要求服务器确保它们是唯一的并且还让服务器进行查找。此时唯一的问题是,如果“权限”是一个新名称……服务器会做什么?它可以很容易地创建它,但如果它是一个错字,或者只是一个大小写问题怎么办?

实际上,它应该是 ID,并且这些应该在创建用户之前就已经存在。GUI 可以帮助操作员确定这些 ID 是什么(提供“角色”名称列表,但知道如何发送POST带有 ID 的请求)。

作为旁注,请注意没有任何东西可以阻止创建没有权限的用户,并且可以在以后根据需要修改用户拥有的权限集合。

回答实际问题

它归结为两个简单的事情。首先,您可以有多个 URI 引用同一个资源;/permissions/666可能是规范的 URI,但如果用户具有该权限,您也可以通过 找到它/user/{userID}/permissions/666,这两个 URI 可以引用服务器上的相同资源。

第二件事要考虑,这确实使答案看起来很明显(尤其是在这个用例中)。您多久创建一次权限?您可能会制作 10 个,但随后将其中一些分配给数千名用户。因此,试图弄清楚如何在一个请求中处理创建权限和用户资源似乎是可耻的愚蠢。正如我认为我已经表明的那样,重复使用它不是问题。

TL;博士

您提出的解决方案一是要走的路。


一个更具挑战性的话题是如何删除权限。来自单个用户或完全删除它。但是我已经讲了足够长的时间,因此也许另一个答案可以专门针对该细节。

于 2015-08-12T09:38:31.467 回答