rest - Transaction safety in RESTful APIs -


i wonder how establish transaction safety in restful apis, built around single entities.

example

database model:

  • invoice
  • item

user-performed steps in browser:

  1. change order number.
  2. add item.
  3. remove item.
  4. edit item.

requests made:

  1. patch/put invoice data/order number.
  2. post item.
  3. delete item.
  4. patch/put item.

issue

if after of requests above error happens, further calls might mess data integrity. additionally previous requests have made undone. e.g. if deleting item fails, steps 1 , 2 have rewound in order overall invoice how before.

another problem might arise browser crash, dying internet connection, server failure or whatever.

how can 1 make sure actions executed in kind of transaction maintain data integrity , safety?

so thing remember rest "state transfer" bit. not telling server steps needed update resource, telling server state resource should in after update, because have updated on client , transferring new state on server.

so have invoice item on server looks json on server

{     invoice_id: 123,     invoice_description: "some invoice",     invoice_items: [         {item_id: 10, item_desc: "large item", order_amount: 34},         {item_id: 11, item_desc: "small item", order_amount: 400}     ] } 

and user wants edit invoice single atomic transaction. firstly invoice server. says "give me current state of invoice"

get /invoices/123 

the user edits invoice anyway want. decide number of large items should 40 not 34. decide delete small items completely. , decide add item of "extra small" items invoice. after user has edited invoice client has following invoice

{     invoice_id: 123,     invoice_description: "some invoice",     invoice_items: [         {item_id: 10, item_desc: "large item", order_amount: 40},         {item_id: 30, item_desc: "extra small item", order_amount: 5}     ] } 

so client has invoice in different state server. user wants send server stored, puts new state of invoice server.

put /invoices/123 

which says "here new state of resource."

now depending on how fancy want validation server can accept new state invoice in is, or can whole load of validation each change. how want you.

you @ least want check no other client has put updated invoice onto server while user editing copy of invoice on client. can checking various headers of http requests (such etag header http://en.wikipedia.org/wiki/http_etag)

if reason server decides update not valid fails entire put request. gives transactions in http. require should either work or fail. if fails servers responsibility make sure resource has not been effected failed request. implantation point of view on server validation of new json , attempt save new data database within db transaction. if fails database kept in original state , user told put didn't work.

if request fails user should returned http status code , response explains why put require failed. might because else has edited invoice while user thinking changes. might because user trying put invoice invalid state (say user tried put invoice no items , breaks business logic of company).

you can of course develop uri scheme allows editing of individual items in invoice, example

get /invoices/123/items/10 

would give item id 10 invoice id 123. if have allow editing of these resources independently of each other. if delete item 10 sending delete command

delete /invoice/123/items/10 

that action must independent transaction. if other requests depend on must instead detailed above, updating invoice in single request. should never able put resource invalid state through single http request, or put way should never require multiple http requests resource valid state (and never require string of http requests work in order valid)

hope helps


Comments

Popular posts from this blog

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -