在RESTful URL中使用动词和形容词的替代方法

在RESTful URL中使用动词和形容词的替代方法,rest,api,restful-url,Rest,Api,Restful Url,我想向我的RESTAPI添加操作,以便在不同的“存储”之间移动“资源” 例如,假设我的资源通常通过以下URL访问: /resources /resources/{resourceId} 现在假设我想“停用”某个资源,即从概念上将其移动到另一个子文件夹。实现这一点的最直接方法如下所示 “停用”资源,即使其在/resources下不可用。从概念上讲,它将对象“移动”到“/resources/deactivated/”子文件夹: POST /resources/{resourceId}/deacti

我想向我的RESTAPI添加操作,以便在不同的“存储”之间移动“资源”

例如,假设我的资源通常通过以下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    

这个API对我来说似乎相当直观。但它似乎违反了我在RESTAPI的许多最佳实践文章中看到的“偏好名词”规则:我使用动词和形容词而不是名词

注意,我可能有所有端点的参数,例如GET/resources/deactivated?createdBefore=01022017

我的RESTAPI有更好的替代方案吗?也就是说,更安静,但不缺乏直觉

我可以找到关于该主题的好资源:

GitHub使用动词POST/gists/:id/star、DELETE/gists/:id/star: 关于需要寻找“另一种对象类型”的观点很好:
活动资源真的与停用资源有那么大的不同吗?考虑一下拥有跟踪活动性的属性。您总是可以过滤掉它们,例如

GET /things?active=true
你可以用microPUT改变这个属性

PUT /things/{id}/active
false
如果一个事物和一个被停用的事物在概念上是不同的,那么有两个独立的端点是合理的。我会使用

POST `/deactivated-things`
{
    "thing": "/things/12"
}

您应该尽量避免使用具有多重含义的路径。例如,不要这样做:

/resources/{id}
/resources/deactivated/{id}

不要在/resources之后重载路径段的含义。

活动资源与停用资源真的有那么大的不同吗?考虑一下拥有跟踪活动性的属性。您总是可以过滤掉它们,例如

GET /things?active=true
你可以用microPUT改变这个属性

PUT /things/{id}/active
false
如果一个事物和一个被停用的事物在概念上是不同的,那么有两个独立的端点是合理的。我会使用

POST `/deactivated-things`
{
    "thing": "/things/12"
}

您应该尽量避免使用具有多重含义的路径。例如,不要这样做:

/resources/{id}
/resources/deactivated/{id}

不要在/resources之后重载路径段的含义。

首先,请记住REST代表代表状态转移

这一切都与资源及其状态有关。诸如activate、deactivate和move之类的操作都是关于用新的表示形式替换资源的当前状态,您不需要URL中的动词来表示这些操作

例如,要替换资源的状态,可以在PUT请求的有效负载中发送资源的新表示:

可以理解为将由[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]标识的资源文件夹。

首先,请记住REST代表代表代表性状态传输

这一切都与资源及其状态有关。诸如activate、deactivate和move之类的操作都是关于用新的表示形式替换资源的当前状态,您不需要URL中的动词来表示这些操作

例如,要替换资源的状态,可以在PUT请求的有效负载中发送资源的新表示:

可以理解为将由[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]标识的资源文件夹替换为请求有效负载中发送的文件夹。

感谢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”


似乎是补丁的经典案例:

感谢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”

似乎是PA的经典案例
TCH:

有一件事你从来没有见过,它会和REST一起被提及:

不要将REST与web应用程序或漂亮的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。

REST中从未提到过一件事:

不要将REST与web应用程序或漂亮的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。

我喜欢你的答案,因为它让我更好地理解REST方法。然而,我不认为简单地更改“status”属性在我的情况下是可以接受的,因为“GET/resources”不应该返回停用的属性。@Alexander要获取所有可以请求GET/api/resources的资源。它将返回活动的和非活动的。要筛选资源集合,可以使用查询参数,如status。因此GET/api/resources?status=active将返回活动的,而GET/api/resources?status=inactive将返回非活动的。您可以假定查询参数的默认值。如果状态为ommited,则假设您只想要活动的。我不同意GET/resources'应该返回所有对象,而不管特定属性的值如何,否则会非常混乱。但另一方面,它不应该返回“已停用”的属性,这意味着它不仅仅是一个常规属性。@Alexander请查看GitHub API to:GET/issues。filter query参数可用于指示返回哪类问题。如果未提供任何值,则使用指定的值作为默认值。谢谢Cassio。嗯,我确信。他们在主旨上加了一个带“PUT”的星号。我喜欢你的答案,因为它让我更好地理解REST方法。然而,我不认为简单地更改“status”属性在我的情况下是可以接受的,因为“GET/resources”不应该返回停用的属性。@Alexander要获取所有可以请求GET/api/resources的资源。它将返回活动的和非活动的。要筛选资源集合,可以使用查询参数,如status。因此GET/api/resources?status=active将返回活动的,而GET/api/resources?status=inactive将返回非活动的。您可以假定查询参数的默认值。如果状态为ommited,则假设您只想要活动的。我不同意GET/resources'应该返回所有对象,而不管特定属性的值如何,否则会非常混乱。但另一方面,它不应该返回“已停用”的属性,这意味着它不仅仅是一个常规属性。@Alexander请查看GitHub API to:GET/issues。filter query参数可用于指示返回哪类问题。如果未提供任何值,则使用指定的值作为默认值。谢谢Cassio。嗯,我确信。他们在主旨上加了一个带“PUT”的星号。