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:
- change order number.
- add item.
- remove item.
- edit item.
requests made:
patch
/put
invoice data/order number.post
item.delete
item.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
Post a Comment