一个宁静的服务API设计问题

时间:2013-08-06 05:55:52

标签: rest wcf-rest restful-architecture

关于restful service API设计的一个问题。我不确定如何做到这一点。请给我一些建议。

我的情况是这样的。我有一个用户资源和权限资源。

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

用户可以拥有多个权限;一个权限可以用于许多用户;这是多对多的关系。

通常情况下,我们可以说权限属于用户,因此我们有一个API:

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

当我们想要在权限和用户之间建立关系时,这里有两个选项。

  1. 我们可以先使用POST:http://www.sample.com/rest/permissions 使用权限正文,然后POST: http://www.sample.com/rest/users/{userId}/permissions有一套 许可ID。我不确定是否还有其他的API 像这样设计。

  2. 我们只能使用一个API:     http://www.sample.com/rest/users/{userId}/permissions有一个     权限对象内容。在这种方法中,我做了两件事     选项1中的描述。缺点是我们不能再重复使用     创建权限,看起来一个用户可以有多个     权限,但一个权限仅由一个用户使用,遵守     我们的第一次设计但这对用户来说非常简单。

  3. 如果您对此主题有任何经验,欢迎提出任何建议。

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

创建用户

  • POST:/ users /
  • return:{userid}

创建权限

  • POST:/ permissions /
  • return:{permid}

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

将用户添加到权限空间

  • PUT:/ permissions / users / {userId} /

或将用户添加到权限空间

  • PUT:/ permissions / users /
  • BODY:{[userid1,userid2,...]}

向用户空间添加权限

  • PUT:/ users / permissions / {permId} /

或向用户空间添加权限

  • PUT:/ users / permissions
  • BODY:{[permid1,permid2,...]}

答案 2 :(得分:1)

资源

首先让我们来解决一下“资源”问题。和'集合'你会的。

  • /users/permissions一个不错的简单开头,每个都分别是所有用户和所有权限的集合。
  • /users/{id}/permissions/{id},每个都分别是用户或权限的单一资源。
    • 用户可能会有" name"," sign-up-date"," id"等字段。等
    • 权限可能包含" name"," creation-date"," id"等

到目前为止很简单。无论你从哪里开始,这两种类型的资源仍然作为独立实体存在,用户没有权限,权限也没有用户。但现在我们需要将这些链接在一起吗?首先,让我们展示一个概念,这个概念似乎让大多数人失去了它的简单性......

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

此概念也可以应用于权限。因此,我们还会添加/users/{id}/permissions,这两种资源都可以作为您可以调用GET的资源,但也可以作为'链接'在GET通过/users/{id}的资源中(因此开始使用html的 hyper 部分)。那回报是什么呢?它可能是这样的:

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

这些资源是否属于'用户,没有。他们需要做,不。那么如果你GET这些权限资源之一呢?

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

然后我们去了最后一行,就像用户拥有一组权限一样,权限包含了一组用户。 (我想你可以找出那些看起来像的东西)

创建资源

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

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

服务器将生成' id'和'注册日期'为了你。权限列表可以允许' id'或者名字'要使用,后者要求服务器确保它们是唯一的,并且服务器也要查找。目前唯一的问题是,如果获得“许可”的话。是一个新名称......服务器做什么?它可以很容易地创建它,但如果它是一个错字,或只是一个大写问题怎么办?

实际上,它应该是ID,并且这些ID必须在创建用户之前存在。 GUI可以帮助操作员计算出这些ID的位置(提供一个'角色名称列表,但知道如何发送带有ID的POST请求)。

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

回答实际问题

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

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

TL; DR

您提出的第一个解决方案是可行的方法。

要讨论的更具挑战性的主题是如何删除权限。来自单个用户或完全删除它。但是我已经走了很长时间,所以也许另一个答案可以专注于这个细节。