I have a normal, basic REST api like:
/
GET - list
POST - create
/<id>
GET - detail
PUT - replace
PATCH - patch
DELETE - delete
When a POST comes in to /
, I usually create an object and make a new id. Some (one) of the fields are (is) required to be unique. So, a POST with such duplicate data could result in:
PUT
/PATCH
to /<id>
and update the existing record4XX
1
seems out: the request is either bad or I can deal with it. What is the correct way to handle this situation?
@StevenFisher is correct. 409 Conflict is the correct response.
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.
For instance, a GET on / might tell a client that they can create users as follows
HTTP/1.1 200 OK
<users href="/">
<create href="/" method="post">
<username type="xs:token" cardinality="required"/>
<password type="password" cardinality="required"/>
</create>
... other hypermedia controls, like search ...
</users>
Following the hypermedia control and trying to create a user with the username "Skylar Saveland" might result in
HTTP/1.1 409 Conflict
<users href="/">
<create href="/" method="post">
<username type="xs:token" cardinality="required"
error="The username 'Skylar Saveland' is already taken. Please select another username"/>
<password type="password" cardinality="required"/>
</create>
... other hypermedia controls, like search ...
</users>
Similarly, trying to create a user without a password might result in
HTTP/1.1 409 Conflict
<users href="/">
<create href="/" method="post">
<username type="xs:token" cardinality="required"/>
<password type="password" cardinality="required"
error="A password must be specified"/>
</create>
... other hypermedia controls, like search ...
</users>
or you might have multiple errors, e.g.,
HTTP/1.1 409 Conflict
<users href="/">
<create href="/" method="post">
<username type="xs:token" cardinality="required"
error="The username 'Skylar Saveland' is already taken. Please select another username"/>
<password type="password" cardinality="required"
error="A password must be specified"/>
</create>
... other hypermedia controls, like search ...
</users>
NOTE: An appropriate media type will need to be created to go along with the above, which will explain the structure of the hypermedia controls (including the error attributes on the forms) and define the meaning of the various element names (e.g., users, username, password, etc).