RESTful处理详细记录更新的方法

3
如果我需要更新许多详细行,我的Web API控制器方法可能是这样的,使用RPC风格:
[Route("api/updateAccountDetailStatus")]
[HttpGet]
public IHttpActionResult UpdateAccountDetailStatus(int accountId, string status)

这将会将与该账户相关的所有详细行更改为新状态。

在尝试采用RESTful方法时,我的猜测是应该是这样的:

PATCH /accounts/110
{
  "status": "hold"
}

[Route("api/accounts/id")]
[HttpGet]
public IHttpActionResult Account(Account account)

我不喜欢的是API控制器现在需要询问对象如何处理它。在这种情况下,它将更改所有详细行以达到新的状态。但是如果有人调用该补丁并发送一个不同的属性来修改呢?那我现在必须根据情况改变行为吗?是否有更好的方法?


抱歉,您能否解释一下“询问对象”和“如果有人调用该补丁并发送不同的属性进行修改”的意思?您是指需要涉及到事务吗? - Aliostad
当调用者更改状态时,API方法需要调用某个逻辑方法来更新数据库中的所有详细记录。现在,如果调用者更新了另一个属性而不是状态呢?也许现在我们只需要更新那个属性?或者也许这意味着我们需要启动另一个完全不同的操作?因此,API方法需要知道哪个属性发生了变化,以便执行适当的操作。这有帮助吗? - Bob Horn
我明白,你的意思是这不是真正的PATCH,我同意,它是一种特殊的操作,需要自己的动词。 - Aliostad
1个回答

1

我理解你的困境。一方面,你希望保持真实性,不在URI中使用动作名称(change、update等),另一方面,这是一个特殊过程,不是真正的PATCH。

因此,为了这个文章,我做了一些工作,允许通过发送类型定义操作,甚至在Web API中创建了一种方式来实现这一点。

这里提供了示例代码。

基本上,您公开这些作为POST或PUT(取决于它们是否具有幂等性),并且资源将有多个POST或PUT。例如:

GET /api/InventoryItem [gets all items]
GET /api/InventoryItem/{id} [gets detail of a single item]
POST /api/InventoryItem [creates an item]
POST /api/InventoryItem/{id}* [checks in stock items to the inventory]
POST /api/InventoryItem/{id}* [removes stock items from the inventory]
PUT /api/InventoryItem/{id} [renames an item]
DELETE /api/InventoryItem/{id} [de-activates an item]

这是我迄今为止对于这些类型资源的唯一解决方案。

更新

基本上,您需要将其公开为PUT(因为我想它是幂等的),位于api/accounts/id,发送一个表示消息类型的有效负载。
PUT api/accounts/id

{"detailBatchStateChange": "hold"}

我有点困惑。您能否根据我的情况提供一个调用示例?其中一种选择可能是这样的:/accounts/{accountId}/detailBatchStateChanges。该方法将知道如何使用状态更新所有详细记录(状态也必须以某种方式传递)。但现在我可能正在远离“正确”的REST,这可能表明REST在这种情况下不起作用? - Bob Horn
更新了。我相信它是可以的 - 我的意思是REST已经涵盖了它。其中一个原则是自描述消息,因此我们应该能够知道如何使用不同的消息针对同一资源进行操作。 - Aliostad
谢谢您的更新。那么,您的方法意味着API方法必须询问对象以了解要执行的操作类型,对吗?而如果我像这样做:/accounts/{accountId}/detailBatchStateChanges,那么该方法将不需要检查传入的对象就知道该怎么做,对吗?为什么前者会更好呢? - Bob Horn
你不必这样做,我的示例展示了如何找出对象的类型,并根据传递的Content-Type信息找到正确的操作(它是一个扩展参数)。它保持了纯洁性,但是否值得麻烦就取决于你了。 - Aliostad
1
我接受了你的答案,因为它似乎是真正的REST方式来实现。不过,我还是倾向于采用更RPC式的方法。:) 感谢你的思考。 - Bob Horn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接