Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most appropriate HTTP status code for an already processed POST request?

Tags:

rest

http

I have a RESTful API that is used by another internal application that post updates to it.

The problem is that some unexpected peaks occur and, during those times, a request might take longer than 60 seconds (the limit defined by the load balancer, which I cannot change) to respond, which causes a 504 Gateway Timeout error.

When the latter application gets such response, it will retry the request again after 10 minutes or so.

This caused some requests to be processed twice, because the first request was successful, but took more than 60 seconds.

So I decided to use Idempotency Keys in the requests to avoid this problem. The issue is that I don't know what I should return in this case.

Should I just stick with 200 OK? Should I return some 4xx code?

like image 741
Henrique Barcelos Avatar asked Jan 27 '23 16:01

Henrique Barcelos


2 Answers

I'd say it highly depends if it is an error for you or not. But I'd say the exact response code is more a matter of taste rather than best practice. But since I guess you're rejecting the duplicated requests, you want to report an error code such as 409 Conflict:

Indicates that the request could not be processed because of conflict in the current state of the resource, such as an edit conflict between multiple simultaneous updates.

https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors

Whenever a resource conflict would be caused by fulfilling the request. Duplicate entries and deleting root objects when cascade-delete is not supported are a couple of examples.

https://www.restapitutorial.com/httpstatuscodes.html

like image 147
maio290 Avatar answered Jan 30 '23 07:01

maio290


A potentially useful reference is RFC 5789, which describes the PATCH method. Obviously, you aren't doing a patch, but the error handling is analogous.

For instance, if you were sending a JSON Patch document, then you might be ensuring idempotent behavior by including a test operation that checks that the resource is in the expected initial state. After your operation, that check would presumably fail. In that case, the error handling section directs your attention to RFC 5789 -- section 2.2 outlines a number of different possible cases.

Another source of inspiration is to look at RFC 7232 which describes conditional requests. The section on If-Match includes this gem:

An origin server MUST NOT perform the requested method if a received If-Match condition evaluates to false; instead, the origin server MUST respond with either a) the 412 (Precondition Failed) status code or b) one of the 2xx (Successful) status codes if the origin server has verified that a state change is being requested and the final state is already reflected in the current state of the target resource (i.e., the change requested by the user agent has already succeeded, but the user agent might not be aware of it, perhaps because the prior response was lost or a compatible change was made by some other user agent).

From this, I infer that 200 is completely acceptable if you can determine that the work was already done successfully.

like image 27
VoiceOfUnreason Avatar answered Jan 30 '23 06:01

VoiceOfUnreason