假设我有这个URI端点:
:GET /v1/permissions
选择版本1的所有权限。
一个人也可以要求:
:GET /permissions
这将要求使用最新的默认版本的所有权限。
现在,我想从特定用户中选择所有权限。
我想知道在URI端点中或在HTTP请求标头中或作为GET参数发送用户标识符的正确和受人尊敬的方式是什么。
例如:
方法1:
:GET /v1/groups/:id/permissions
方法1.1:
:GET /v1/:id/permissions
方法2:
:GET /v1/permissions,
"If-Match": "[REPLACE_ID_HERE]" (header)
方法3:
:GET /v1/permissions/?groups=REPLACE_ID_HERE
所有这些都可以使用。
但是哪种方法合适?
答案 0 :(得分:3)
但是哪种方法合适?
这是一个常见的误解。
REST体系结构样式不强制执行任何URI设计(请参见下面的注释)。完全由您来选择可以更好地标识您的资源的URI。
URI语法在RFC 3986中定义。通常,该路径以 hierarchical 形式组织(各段之间用/
分隔),并且可以在查询组件中(从?
开始包含非分层数据)。
这些方法似乎可以识别特定组的权限:
/v1/groups/:id/permissions
/v1/permissions?groups=id
“正确” 方法将取决于您的需求以及您对API建模的方式。在第一种方法中,层次结构表示权限属于特定组(权限依赖依赖于要存在的组)。第二种方法更像按组过滤权限集合。
注1:在Roy T的chapter 5中描述了REST体系结构样式。Fielding的论文定义了一组约束,应用程序必须遵循这些约束遵循这样的架构。但是,它并没有说明URI必须是什么样。
注释2: Martin Fowler撰写的popular article的示例,解释了伦纳德·理查森(Leonard Richardson)定义的模型。 >看起来友好且易于阅读的URI结构。
答案 1 :(得分:2)
提前两点:
其中一个标准是 REST Urls特定于资源,并且嵌入在这些Urls中的ID引用了相同类型的资源。因此GET /groups/:groupdId
是 orthodox (符合大多数程序员期望的标准实现),而GET /groups/:permissionId
不是。
回到您考虑的4个替代方案:
方法1:
:GET /v1/groups/:id/permissions
是正统的,因为由端点管理的资源的类型为Group
,而:id是组ID。
方法1.1:
:GET /v1/:id/permissions
是非正统的,因为没有迹象表明Url指的是哪种资源类型。
方法2:
:GET /v1/permissions,
"If-Match": "[REPLACE_ID_HERE]" (header)
这是非正统的,因为资源ID应该作为Url的一部分传递。
方法3:
:GET /v1/permissions/?groups=REPLACE_ID_HERE
是正统的,因为这里的资源为Permission
,而groupId
被用作过滤器,对于该过滤器,请求参数是适当的手段。
答案 2 :(得分:0)
设计REST API的最常见方法是遵循资源(和-或子资源)结构。也就是说,如果使用单个资源GET,PUT(update)或DELETE,则api url将以您的资源名称开头,后跟该资源的唯一ID。
例如: 1. / users / $ unique_user_id-HTTP GET-获取单个用户的详细信息。
/ users / $ unique_user_id-HTTP PUT-使用相关数据更新由ID标识的用户详细信息。
/ users / $ unique_user_id-HTTP DELETE-删除ID标识的用户。
如果您的案件处理的是两种资源之间的已建立的关系,则可以将其作为父项的子资源来处理。 例如: / users / $ user_id / permissions / groups / $ group_id / permissions
如果您不需要获取多种资源的权限(此类型的过滤),则该模型将适用 例如: / permissions?group_ids = 1,2,3 / permissions?user_ids = 4,5,6
答案 3 :(得分:-2)
根据REST规范,您首先需要确定所请求的基础资源是什么。资源的名称在URI中排在第一位。您的情况就是许可。因此,URI将以权限开头,并带有可选的版本前缀(因为整个API均已版本化)
在资源名称之后,您需要提及特定资源或查询参数以获取广泛的列表。现在,根据要检索的内容,您有两个选择。 1)一个人的权限:在这种情况下,您需要放置查询参数,因为api本身无法猜测ID的含义。因此它将是权限/?personId = 123 2)特定权限的权限详细信息:当您预先获取了权限列表时使用,可能是上述api的结果。在这种情况下,标识符将属于资源本身,因此它将被指定为资源标识符,即权限/ 5e55,其中5e55是正在寻求详细信息的指定权限的主键。
这种设计的主要复杂性是正确识别资源的主要标识符和次要标识符... 主要标识符直接放在类型2中,辅助标识符指定为查询参数。
所有人都说,从技术上讲,只要您提供URI的解析逻辑,任何方法都不会阻止任何一种请求样式的运行。 REST只是说URI应该能够正确识别资源,并不强加实现要求。