I've found that Http 207 can be used for bulk insert/delete/... etc. operations where we potentially have multiple items being inserted and partial success is ok from business perspective.
I wonder if the same thing applies if we have API Post calling some external services?
Example business scenario:
We have HttpPost endpoint that is creating an order.
HttpPost:
/api/order/
Now let's assume that this endpoint besides creation of an Order would be calling external service to also print a label for that order and another one to send some kind of confirmation via REST to external 3rd party system.
Now in this scenario we assume that creation of Order is a must for the success of this operation but both printing and external REST call can return error message. Potentially that is besides our control.
Now from what I've read the options on how to return this information would be:
{
"isSucess": true,
"isFailure": true,
"erorMesage": "string"
}
Now I wonder which would be most suitable ? I'm kind of leaning towards 502 error or 207 since they in my opinion provide the most information about the actual state of the system.
This is a design question for how to use REST web service for a nested distributed transaction. There are many suitable answers. Here is my take on this, where I address each of your points, while referring to the REST spec.
allows user agents to collaboratively author contents directly in an HTTP web server
WebDAV is not exactly built for distributed transactions. Servers that can handle return code 207 need to have the WebDAV module installed in them. You may not even get support in several REST libraries for this return code. For example this API docs does not have code 207. https://docs.oracle.com/javaee/7/api/javax/ws/rs/core/Response.Status.html (this is an edge case, but it helps make the point).
"Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. "
The server is not at fault here. It has created the entity.
POST /api/order/
, return a reference to the order and process the steps asynchronously. There are multiple transactions involved in this request - printing label, updating third party REST endpoint, etc. These can be updated in the order
resource.
For example, the POST /api/order/
can return in this format:HTTP STATUS 202 (Accepted) { "order": { "id": "1234567" } }
The client should check for the complete status with GET /api/order/
, which will return the individual status:
{ "id": 1234567, "label_printed": "failed", "third_party_updated": "success"}
If any of the sub-transactions of an order has failed and should be reprocessed, it is an update on the existing order, and a call to PUT /api/order/
, because the PUT
method is to update the resource. The server will take the PUT request and retry the transactions as needed.
Here are some additional answers that are suitable for this question: