Bob Horn
Bob Horn

Reputation: 34297

RESTful Way to Handle Updating Detail Records

If I need to update many detail rows, my Web API controller method might look like this, using an RPC style:

[Route("api/updateAccountDetailStatus")]
[HttpGet]
public IHttpActionResult UpdateAccountDetailStatus(int accountId, string status)

That would change all of the detail rows, associated with that account, to the new status.

In trying to take a RESTful approach, my guess is that it would be something like this:

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

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

What I don't like about that is now the API controller method needs to interrogate the object to see how to handle it. In this case, it would be changing all of the detail rows to that new status. But what if someone calls that patch and sends a different property to modify? Now I have to change behavior based on that? Is there a better way?

Upvotes: 3

Views: 436

Answers (1)

Aliostad
Aliostad

Reputation: 81660

I see the conundrum. On one hand, you would like to stay true and not have action names (change, update, etc) in your URI, and on the other hand, this is a special procedure and not quite a PATCH really.

So, for this article I did some work to allow the action to be defined by the type of the message sent, even created a means of doing that in Web API.

The sample code for this is here.

Essentially you expose these as POST or PUT (depending on whether they are idempotent or not) and the resource will have multiple POST or PUT against it. For Example:

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]

This is the only solution I have had so far for these types of resources.

UDPATE

Essential you would expose this as PUT (since I imagine it is idempotent) at api/accounts/id sending a payload signifying type of the message:

PUT api/accounts/id

{"detailBatchStateChange": "hold"}

Upvotes: 1

Related Questions