我有一个代表一组物理设备的资源。
调用GET v1/devices/
会产生以下结果:
[
{
"MacAddress": "DD-22-33-15-15-66",
"Name": "Test Device",
"State": "Approved"
},
{
"MacAddress": "E5-21-56-44-11-B6",
"CompanyId": "Another Test Device",
"State": "Pending"
}
]
设备具有状态(重要属性),只能是pending
或approved
,因此以下GET请求也可用:
GET v1/devices/pending
:检索所有待处理的设备GET v1/devices/approved
:检索所有已批准的设备您还可以使用GET v1/devices/EF-55-33-44-54-61
我现在希望能够仅将设备的状态从Pending
更新为Approved
。
以下PATCH调用是否有意义?
PATCH v1/devices/EF-55-33-44-54-61/approve
从某些阅读中,看起来正确的方法就是这样:
[
{"replace": "/state", "value": "approved"}
]
但这对于这样一个特定的更新来说似乎太灵活了。我从不希望更新其他值,也不希望以任何其他方式更改状态。
答案 0 :(得分:1)
我会针对正在修补的对象的URI执行PATCH:
PATCH v1/devices/EF-55-33-44-54-61
没有任何惯例说Web API控制器中的PATCH方法必须允许修补设备对象上的所有属性。如果您只支持对该属性的更新,那就没问题。
虽然上面较长的JSON看起来有点过分,但这也意味着如果以后发生某些变化并且您确实需要PATCH多个属性,那么现在只需要更新控制器以允许它并且JSON保持不变(虽然可以在一次通话中完成多次替换。)
答案 1 :(得分:1)
首先,您不应该使用此URL模式来过滤返回的设备。您使用下面的模式,但恕我直言,这不是最好的方法。
GET v1/devices/<approved|pending>
相反,如果要使用过滤器中的一个或多个属性过滤或限制返回的设备,则应使用如下的QueryString:
GET v1/devices?status=<approved|pending>
请记住,您的URI应仅针对资源,并且在我看来,&#34;已批准&#34;不是一种资源。事实上,它是这种资源的一种状态。在这种情况下,使用QueryString过滤或限制您要处理的资源。转到你的主要问题......
以下PATCH调用是否有意义? PATCH v1 / devices / EF-55-33-44-54-61 / approve
是的,不! :)您可以使用Github使用的相同方法。在Github上,如果你想要&#34;明星&#34;通过他们的API,你必须对子资源&#34; / gist / id / star&#34;进行POST。您可以将其视为&#34;我正在创建子资源明星&#34;。如果你想&#34; unstar&#34;这个要点,你必须在&#34; / gist / id / star&#34;上进行删除。 (我从主要资源中删除子资源星)。
在你的情况下,我会做这样的事情:
POST v1/devices/EF-55-33-44-54-61/approval
您可以将其视为&#34;我正在创建子资源批准&#34;。也许它会有不同的状态,例如&#34;批准日期&#34;,&#34;批准它的用户&#34; ...
DELETE v1/devices/EF-55-33-44-54-61/approval
你可能会认为它是&#34;我正在删除子资源&#34;批准&#34;现在这个设备不再具有这种关联。
答案 2 :(得分:1)
以下PATCH调用是否有意义?
PATCH v1 / devices / EF-55-33-44-54-61 / approve
REST不是RPC,所以你不应该将你的操作绑定到URI,你应该将它们绑定到方法(动词) - URI(名词)对。所以在你的情况下,/approve
动词不是RESTish,你的请求体也不是RESTish,因为它包含一个命令而不是一个资源表示。
我会使用类似的东西:
PUT v1/devices/EF-55-33-44-54-61/state "approved"
PATCH v1/devices/EF-55-33-44-54-61 {state: "approved"}
请注意,真正的REST客户端遵循超链接而不是构建URI。那些(在很多事情中)是什么使它们松散耦合。