REST设计 - 针对特定更新的PATCH

时间:2014-11-13 11:25:15

标签: rest asp.net-web-api patch asp.net-web-api2 restful-url

我有一个代表一组物理设备的资源。

调用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"
  }
]

设备具有状态(重要属性),只能是pendingapproved,因此以下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"}
]

但这对于这样一个特定的更新来说似乎太灵活了。我从不希望更新其他值,也不希望以任何其他方式更改状态。

3 个答案:

答案 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。那些(在很多事情中)是什么使它们松散耦合。