在 RESTful URL 中使用动词和形容词的替代方法
Posted
技术标签:
【中文标题】在 RESTful URL 中使用动词和形容词的替代方法【英文标题】:Alternatives of using verbs and adjectives in RESTful URL 【发布时间】:2017-04-11 21:16:31 【问题描述】:我想向我的 REST API 添加操作,以便在不同“商店”之间移动“资源”。
例如,假设我的资源通常通过以下 URL 访问:
/resources
/resources/resourceId
现在假设我想“停用”某些资源,即从概念上将其移动到另一个子文件夹。允许这样做的最直接的方法如下。
“停用”资源,即使其在 /resources 下不可用。从概念上讲,它将对象“移动”到“/resources/deactivated/”子文件夹:
POST /resources/resourceId/deactivate
或者:
POST /resources/deactivated/resourceId
获取所有停用的对象:
GET /resources/deactivated
反转“停用”操作,即从概念上将对象从“/resources/deactivated/”子文件夹移回主文件夹(“/resources”) .
要么
POST /resources/resourceId/reactivate
或者
POST /resources/deactivated/resourceId/restore
这个 API 对我来说似乎相当直观。但这似乎违反了我在许多关于 REST API 的最佳实践文章中看到的“首选名词”规则:我使用动词和形容词而不是名词!
请注意,我可能有所有端点的参数,例如GET /resources/deactivated?createdBefore=01022017
我的 REST API 是否有更好的替代方案? IE。更 RESTful,但并非不那么直观?
我可以找到关于该主题的好资源:
Confusion Between Noun vs. Verb in Rest URLs GitHub 对动词的使用(POST /gists/:id/star, DELETE /gists/:id/star):https://***.com/a/19648997/1847482 关于需要寻找“另一种对象类型”的要点:https://***.com/a/2022938/1847482【问题讨论】:
【参考方案1】:首先,请记住 REST 代表 Representational State Ttransfer。
这都是关于资源及其状态。 activate、deactivate 和 move 等操作都是用新的表示替换资源的当前状态,不需要动词在 URL 中表达此类操作。
例如,要替换资源的状态,您可以在PUT
请求的负载中发送资源的新表示:
PUT /api/resources/[id]/status HTTP/1.1
Host: example.org
Content-Type: application/json
"status" : "active"
可以理解为将[id]
标识的资源状态替换为请求载荷中发送的状态。
然后您可以通过以下方式获取具有特定状态的资源:
GET /api/resources?status=active HTTP/1.1
Host: example.org
Accept: application/json
可以理解为给我一个状态为active
的所有资源的表示。
例如,要将资源移动到另一个文件夹,您可以:
PUT /api/resources/[id]/folder HTTP/1.1
Host: example.org
Content-Type: application/json
"target" : "draft"
可以理解为将[id]
标识的资源所在文件夹替换为请求payload中发送的文件夹。
【讨论】:
我喜欢您的回答(已投票),因为它让我更好地理解了 REST 方法。然而,在我的情况下,我不认为简单地更改“状态”属性是可以接受的,因为“获取/资源”不应该返回已停用的属性。 @Alexander 要获取所有资源,您可以请求GET /api/resources
。它将返回活动和非活动的。要过滤resources
集合,可以使用status
之类的查询参数。所以GET /api/resources?status=active
将返回活动的,而GET /api/resources?status=inactive
将返回非活动的。您可以假设查询参数的默认值。如果status
被省略,假设您只想要活动的。
我不同意。 'GET /resources' 应该返回所有对象,而不考虑特定属性的值,否则会很混乱。但另一方面,它不应该返回“停用”的,这意味着它不仅仅是一个常规属性。
@Alexander 查看list issues 的 GitHub API:GET /issues
。 filter
查询参数可用于指示要返回的问题类型。如果未提供值,则默认使用 assigned
值。
谢谢卡西欧。嗯,深信不疑。他们也用“PUT”在一个要点上加了一颗星。 developer.github.com/v3/gists/#star-a-gist.【参考方案2】:
活动资源与停用资源真的有那么大的不同吗?考虑只拥有一个跟踪active
ness 的属性。您可以随时将它们过滤掉,例如
GET /things?active=true
您可以使用 microPUT 仅更改该属性
PUT /things/id/active
false
如果thing
和deactivated-thing
在概念上不同,则有两个单独的端点是合理的。我会在他们之间移动使用
POST `/deactivated-things`
"thing": "/things/12"
和
POST `/things`
"deactivated-thing": "/deactivated-things/12"
您应该尽量避免一条具有多重含义的路径。例如,不要这样做:
/resources/id
/resources/deactivated/id
/resources
之后的路径段的含义不要重载。
【讨论】:
【参考方案3】:感谢 Cassio 强调“改变对象状态”的方法。
我自己的完整性回答:
PATCH /resources/resourceId with body "active":false -- deactivate a resource
PATCH /resources/resourceId with body "active":true -- restore a resource
GET /resources -- return all 'normal' resources
GET /resources?includeInactive=true -- return all resources including the deactivated ones
GET /resources/resourceId -- return the resource
(“GET”检索到的资源将包含“active=true/false”属性)。
似乎是 PATCH 的经典案例:REST API PATCH or PUT
【讨论】:
【参考方案4】:在 REST 中你从未见过的一件事:
不要将 REST 与网络应用或漂亮的 url 混淆。
例如。当用户登录以编辑他们的帐户时,您会显示
www.example.com/home
www.example.com/account
www.example.com/profile
而不是
// www.example.com/users/id ...
www.example.com/users/433563444335634443356344
www.example.com/users/433563444335634443356344/edit
我认为这是许多开发人员感到困惑的地方。 REST 非常适合 API,但就 Web 应用程序而言,它应该用作表单操作端点或 ajax 的内部 API,但不一定用作漂亮的 url。
【讨论】:
以上是关于在 RESTful URL 中使用动词和形容词的替代方法的主要内容,如果未能解决你的问题,请参考以下文章