I'm designing a REST interface and I'm puzzled by what should the insert/update/delete verb return (as content of the response). Consider an inteface for Invoice entities, accessible at api/invoices:
GET /api/invoicesreturns a list of invoicesGET /api/invoices/123returns the invoice with ID 123POST /api/invoicesadds a new invoice (ID generated on server)POST /api/invoices/123updates invoice with ID 123DELETE /api/invoices/123deletes invoice with ID 123
Its pretty obvious what the first two method should return, but how about the insert/update/delet ones? An obvious answer is that add should return the newly created item (ie. exactly the same response as GET /api/invoices/id), update should return the updated item (again, same as a GET) and delete should probably return nothing (empty content). This all makes sense and is consitent.
But my problems start when considering items that are not so simple as an Invoice entity. For instance consider an add request that not only adds the item, but actually needs to return some extra information about the add operation: the item was accepted (success), the item is a duplicate (success with info), the item was ignored (success with info, I won't eneter into details why), the item was rejected (failure). Also in my case there is extra information I want to return, like a 'response' info pre-set for the bucket into the newly added items falls. I considered placing all the extra information in the http headers as sort of out-of-band info (like extra status codes in the 200 range and even custom headers) but is a hack, and the 'response' part can be actualy larger than the item itself. So now I'm considering the add verb to return a completely new type, an item that contains the add info (status, response, ID of the new item, perhpas the entire new item). It certainly gets the job done, but I miss the nice symmetry I had before.
Would this be a good practice (when adding an item of type 'foo' the return is of type 'bar') or is something I'll look back in 6 month and pull my hair because I let the cat out of the bag? If I stick with 'any access on foo returns foo, including add', then the client would have to make an extra call after the 'add' operation to retrieve the information it is really interested in (ie. the 'response').