Search code examples
restapiapi-design

Updating a collection the RESTful way


I'm in a situation where I have something similar to shopping cart. I have a set of products with known IDs I then want to create a subset with modified prices and later modify this subset

Superset

[{  
   "productId":1,
   "price":1.99
},
{  
  "productId":2,
  "price":2.99
},
{  
  "productId":3,
  "price":3.99
},
{  
   "productId":4,
   "price":4.99
}]

...

Modified Subset

[{  
   "productId":1,
   "price":1.59
},
{  
  "productId":3,
  "price":2.59
}]

Then I want to modify the subset again to look like

[{  
   "productId":1,
   "price":1.79
},
{  
  "productId":2,
  "price":3.59
}]

All I can think of is client sending a POST request like

{  
   "productsAdded":[  
      {  
         "productId":2,
         "price":3.59
      }
   ],
   "productsModified":[  
      {  
         "productId":1,
         "price":1.79
      }
   ],
   "productsDeleted":[  
      {  
         "productId":3,
         "price":2.59
      }
   ]
}

The constraints are that I would like to avoid multiple calls to correct verbs and not send the entire subset. As the actual objects have many more fields and there are thousands of objects in a subset. The update then saves the state triggers a long running fire and forget task.

The problem I see with this is that client potentially has to create a delta of the state and the server has to reconstruct the state from the message.

This might not be a bad approach, but I am wondering if there are alternative solutions


Solution

  • Updating a collection the RESTful way

    The Atom Publishing Protocol is built around the idea of modifying collections of atom entries in the REST architectural style. You might start out by reviewing that design.

    All I can think of is client sending a POST request like

    That's really close to a JSON Patch representation.

    The idea is that if the client and the server share the same (usually standardized) understanding of the media-type, then they can continue to collaborate even as they are developed independently.

    So using POST to pass a JSONPatch representation of the change to the resource is a good starting point; if you don't like JSONPatch (perhaps because it is domain agnostic), you could define your own more specific media type and use that.

    (Note: though the message type is called "patch", you don't actually need to use the PATCH method in your API. POST on its own, PATCH on its own, or both are all acceptable alternatives.)