Skip to content

Discussion

Overview

HTTP response code for POST when resource already exists Asked 12 years, 7 months ago Modified 2 days ago Viewed 713k times

Report this ad

1275

I'm building a server that allows clients to store objects. Those objects are fully constructed at client side, complete with object IDs that are permanent for the whole lifetime of the object.

I have defined the API so that clients can create or modify objects using PUT:

PUT /objects/{id} HTTP/1.1 ...

{json representation of the object} The {id} is the object ID, so it is part of the Request-URI.

Now, I'm also considering allowing clients to create the object using POST:

POST /objects/ HTTP/1.1 ...

{json representation of the object, including ID} Since POST is meant as "append" operation, I'm not sure what to do in case the object is already there. Should I treat the request as modification request or should I return some error code (which)?

resthttphttp-status-codes Share Improve this question Follow edited Mar 24, 2020 at 17:47 Sławomir Lenart's user avatar Sławomir Lenart 7,29944 gold badges4242 silver badges6161 bronze badges asked Sep 29, 2010 at 21:26 vmj's user avatar vmj 13.1k33 gold badges1717 silver badges1414 bronze badges 7 As of June 2016 FB blatantly sets 200 on registration when email exists – Green Jun 21, 2016 at 11:50 13 Github API returns 422 when trying to create a resource (team/repo) with a name that is already in use – Ken Dec 15, 2016 at 16:44 1 It depends if you consider the existence of the object an error or not. If you process the append, 200 or 204 are the most appropriate response codes. – Suncat2000 Jan 10, 2019 at 13:56 2 In summary its a toss up between 409 Conflict and 422 Unprocessable Entity - I think the weight of answers here points to 409 though and certainly from a human perspective is more readily understandable – danday74 Nov 17, 2020 at 1:11 1 I use 409 for this and 422 for bad forms only. – Anthony O Apr 6, 2021 at 4:00 Show 1 more comment 18 Answers Sorted by:

Highest score (default)

1559

My feeling is 409 Conflict is the most appropriate, however, seldom seen in the wild of course:

The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.

Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.

Share Improve this answer Follow edited Jun 20, 2020 at 9:12 Community's user avatar CommunityBot 111 silver badge answered Sep 29, 2010 at 21:31 Wrikken's user avatar Wrikken 68.9k88 gold badges9696 silver badges136136 bronze badges 28 why not go for 400 Bad Request? For me this looks a bit like a validation error (you are providing wrong payload with illegal id). – manuel aldana Sep 30, 2010 at 18:55 431 400 => "The request could not be understood by the server due to malformed syntax". And the server understands perfectly, but is unable to comply due to a conflict. There is nothing wrong with the request & syntax, only a data problem. A 400 would instantly make me believe the whole mechanism I'm using is flawed, instead of just the data. – Wrikken Sep 30, 2010 at 19:11 90 @Wrikken That is no longer correct. HTTP 400 was changed in RFC 7231 to mean "the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." I'm not saying 400 is correct usage in this case but it could be correct with the new definition of 400. – javajavajavajavajava Jun 21, 2016 at 18:16 34 @javajavajavajavajava: still, duplicate data is not a 'client error' in my mind, but that's in the eye of the beholder of course. – Wrikken Jul 16, 2016 at 23:45 63 I return HTTP 409 with a Location header pointing to the existing/conflicting resource. – Gili Oct 10, 2017 at 18:51 Show 12 more comments

156

It's all about context, and also who is responsible for handling duplicates of requests (server or client or both)

If server just point the duplicate, look at 4xx:

400 Bad Request - when the server will not process a request because it's obvious client fault 409 Conflict - if the server will not process a request, but the reason for that is not the client's fault ... For implicit handling of duplicates, look at 2XX:

200 OK 201 Created ... if the server is expected to return something, look at 3XX:

302 Found 303 See Other ... when the server is able to point the existing resource, it implies a redirection.

If the above is not enough, it's always a good practice to prepare some error message in the body of the response.

Share Improve this answer Follow edited Apr 19, 2022 at 12:57 answered Aug 8, 2018 at 11:58 Sławomir Lenart's user avatar Sławomir Lenart 7,29944 gold badges4242 silver badges6161 bronze badges 4 The request is not duplicating a resource, it is appending data to one. In my opinion, yours is the best answer of all. – Suncat2000 Jan 10, 2019 at 14:09 8 All 4xx errors are the client's "fault." All 5xx errors are the server's "fault." (And submitting duplicate data is something the client has to fix, not the server.) – Paul Draper Apr 19, 2021 at 14:21 @Paul Draper: There is no place for 5xx when the resource already exists. The order of 4xx, 2xx, 3xx is not a coincidence here. It will be mostly 4xx, but others are fair enough in many cases, especially when a client has totally no idea how to deal with a duplicate or it does

According to RFC 7231, a 303 See Other MAY be used If the result of processing a POST would be equivalent to a representation of an existing resource.

You can use Eloquent's exists() method to check whether a record exists This is old, but still a great feature. Eloquent is so smooth! Check if a record exists in Laravel with exists() and doesNotExists()