I’m creating a RESTful API for creating users that enforces unique email addresses:
Successful POST /users: HTTP 201 Created
If I POST the same email address again, what should the response code be? Is 409 Conflict the appropriate response code?
Henke
4,5353 gold badges31 silver badges45 bronze badges
asked Feb 13, 2012 at 22:32
6
Yes, 409 is the most appropriate response code here. Even though you are most likely returning 201 on success, you’re still POSTing to a resource which is described as a collection, and POSTing a duplicate email is definitely a conflict with «the current state of the resource» as a collection. You should return a response body with a description of the problem, and hyperlinks to help resolve the problem, if possible.
answered Feb 14, 2012 at 1:15
fumanchufumanchu
14.4k6 gold badges31 silver badges36 bronze badges
3
I am not really satisfied with returning a 409 Conflict for an existing registered email — in my opinion, it’s not a client error. So let’s take a look at how some big tech companies are handling that case (at least how they are doing it in their WEB Site APIs).
Gmail (Google) returns a 200 OK and a JSON object containing a code which is indicating that the email is already registered.
Facebook is also returning a 200 OK but re-renders the content to a recovery page to give the user the option to recover his/her existing account.
Twitter is validating the existing email by an AJAX call
To another resource. The response of the email validation resource is always a 200 OK. The response contains a JSON object containing a flag to indicate if the email is already registered or not.
Amazon is doing it the same way as Facebook. Returning a 200 OK and re-rendering the content to a notification page to inform the user that the account already exists and provide him/her possibilities to take further actions like login or password change.
So all these APIs returning always a 200 OK and presenting to the client/user either additional content to recover their account or an error message which is raised by the body content of the response.
answered Nov 4, 2018 at 19:53
Paul WasilewskiPaul Wasilewski
9,7725 gold badges45 silver badges49 bronze badges
5
While the accepted answer is correct in showing the correct status code for the task, I want to add that you are introducing a security vulnerability.
If you return a 409 for account registration, you are just exposing a service for account enumeration.
Depends on the application, if the api is public or not, etc, you may want to return a 201 even if the account wasn’t created.
answered Sep 11, 2015 at 19:45
Bart CalixtoBart Calixto
19.2k11 gold badges78 silver badges114 bronze badges
5
+1 to Barts answer — for security reasons. Usually I would agree that 409 is a good status code for sth. that already exists. But in an environment of user accounts/authentication/authorization etc., I would tend to not exposing the existing user accounts in your database.
Of course there are other mechanisms of handling security at this place. If you do not mind to expose a little number of your accounts, you could add a behavior to your application that returns 401 or 403 on numerous 409-events from one IP.
Another option (in general) is to define a status code on your own to have a 2xx that differs from the existing standard 2xx variants. This could be an option if you do not want to handle an «already exists» as an error. However, this would be regarded as non-standard and would have the same unsafe character like a 409 in your concrete example.
answered Sep 14, 2017 at 13:39
iquellisiquellis
9791 gold badge9 silver badges26 bronze badges
I often use the (WebDAV extension) HTTP 422 Unprocessable Entity:
The request was well-formed but was unable to be followed due to semantic errors
answered Feb 13, 2012 at 22:34
GarethGareth
133k36 gold badges148 silver badges157 bronze badges
1
409 => Conflict
That mean.
The request could not be completed due to a conflict.
For example, POST ContentStore Folder API cannot complete if the given file or folder name already exists in the parent location.
answered Jun 3, 2020 at 8:37
For registration it is required to have a code that is different from success 200 code, but not an error 4xx code.
As suggested in HTTP response code for POST when resource already exists look at 3XX:
302 Found
303 See Other
In particular
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.
The concern about exposure of existing addresses to enumerating bots can be addressed by different means such as captcha.
answered Oct 11, 2021 at 20:30
Michael FreidgeimMichael Freidgeim
26.6k16 gold badges152 silver badges172 bronze badges
0
I was thinking 403. From http://www.restapitutorial.com/httpstatuscodes.html:
The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.
Edit: Endpoint — POST /users.
Kevin
29.1k9 gold badges63 silver badges81 bronze badges
asked Aug 1, 2015 at 2:25
Adam ZernerAdam Zerner
17.9k15 gold badges90 silver badges156 bronze badges
4
The normal HTTP error code for situations like this is 409 Conflict:
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.
This should be issued in response to a POST or PUT, typically as part of some sort of RESTful API. It should include a useful error message in addition to the status, and the error should be appropriately encoded (e.g. with XML or JSON).
Obscure HTTP errors are less useful in front-end web services. If you are developing a user-facing website, it’s preferable to simply deliver an HTML page explaining the problem with a standard 200 OK.
answered Aug 1, 2015 at 2:42
0
If you are creating a REST API to create accounts, I would expect the request to be something like:
POST /accounts HTTP/1.1
{userid: "someone@example.com", password: "passw0rd!"}
In this case, I guess an appropriate response code would be 409 Conflict with an error description in the body
HTTP/1.1 409 Conflict
{ error: "Account already exists"}
answered Aug 1, 2015 at 2:48
MvdDMvdD
22.2k9 gold badges66 silver badges93 bronze badges
That status code is for an HTTP error, not what you need. Also, it would be very unhelpful as it does not describe the problem at all.
Why not just send:
Username already exists! Please select another.
answered Aug 1, 2015 at 2:31
LanceLance
3,8244 gold badges21 silver badges29 bronze badges
2
403 is an ok response in my opinion. 409 and 412 are also possible choices.
answered Aug 1, 2015 at 2:43
Vic FVic F
1,1431 gold badge11 silver badges26 bronze badges
Я думал 403. Из http://www.restapitutorial.com/httpstatuscodes.html:
Сервер понял запрос, но отказывается его выполнить. Авторизация не поможет, и запрос НЕ ДОЛЖЕН повторяться. Если метод запроса не был HEAD и сервер желает обнародовать, почему запрос не был выполнен, он ДОЛЖЕН описать причину отказа в объекте. Если сервер не желает предоставлять эту информацию клиенту, вместо этого можно использовать код состояния 404 (Не найден).
Изменить: конечная точка — POST /users.
4 ответа
Лучший ответ
Обычный код ошибки HTTP для подобных ситуаций — 409 Conflict :
Запрос не может быть выполнен из-за конфликта с текущим состоянием ресурса. Этот код разрешен только в ситуациях, когда ожидается, что пользователь сможет разрешить конфликт и повторно отправить запрос. Тело ответа ДОЛЖНО содержать достаточно информации, чтобы пользователь мог распознать источник конфликта. В идеале объект ответа должен включать достаточно информации для пользователя или пользовательского агента, чтобы исправить проблему; однако это может быть невозможно и не требуется.
Это должно быть выполнено в ответ на POST или PUT, обычно как часть какого-либо RESTful API. Он должен включать полезное сообщение об ошибке в дополнение к статусу, и ошибка должна быть соответствующим образом закодирована (например, с помощью XML или JSON).
Неизвестные ошибки HTTP менее полезны во интерфейсных веб-службах. Если вы разрабатываете веб-сайт, ориентированный на пользователя, предпочтительнее просто предоставить HTML-страницу, объясняющую проблему, со стандартным 200 OK.
3
Kevin
1 Авг 2015 в 02:42
На мой взгляд, 403 — нормальный ответ. Также возможны варианты 409 и 412.
0
Vic F
1 Авг 2015 в 02:43
Этот код состояния предназначен для ошибки HTTP, а не для того, что вам нужно. Кроме того, это было бы очень бесполезно, так как оно вообще не описывает проблему.
Почему бы просто не отправить:
Имя пользователя уже занято! Пожалуйста, выберите другой.
0
Lance
1 Авг 2015 в 02:31
I’m creating a RESTful API for creating users that enforces unique email addresses:
Successful POST /users: HTTP 201 Created
If I POST the same email address again, what should the response code be? Is 409 Conflict the appropriate response code?
Henke
4,5353 gold badges31 silver badges45 bronze badges
asked Feb 13, 2012 at 22:32
6
Yes, 409 is the most appropriate response code here. Even though you are most likely returning 201 on success, you’re still POSTing to a resource which is described as a collection, and POSTing a duplicate email is definitely a conflict with «the current state of the resource» as a collection. You should return a response body with a description of the problem, and hyperlinks to help resolve the problem, if possible.
answered Feb 14, 2012 at 1:15
fumanchufumanchu
14.4k6 gold badges31 silver badges36 bronze badges
3
I am not really satisfied with returning a 409 Conflict for an existing registered email — in my opinion, it’s not a client error. So let’s take a look at how some big tech companies are handling that case (at least how they are doing it in their WEB Site APIs).
Gmail (Google) returns a 200 OK and a JSON object containing a code which is indicating that the email is already registered.
Facebook is also returning a 200 OK but re-renders the content to a recovery page to give the user the option to recover his/her existing account.
Twitter is validating the existing email by an AJAX call
To another resource. The response of the email validation resource is always a 200 OK. The response contains a JSON object containing a flag to indicate if the email is already registered or not.
Amazon is doing it the same way as Facebook. Returning a 200 OK and re-rendering the content to a notification page to inform the user that the account already exists and provide him/her possibilities to take further actions like login or password change.
So all these APIs returning always a 200 OK and presenting to the client/user either additional content to recover their account or an error message which is raised by the body content of the response.
answered Nov 4, 2018 at 19:53
Paul WasilewskiPaul Wasilewski
9,7725 gold badges45 silver badges49 bronze badges
5
While the accepted answer is correct in showing the correct status code for the task, I want to add that you are introducing a security vulnerability.
If you return a 409 for account registration, you are just exposing a service for account enumeration.
Depends on the application, if the api is public or not, etc, you may want to return a 201 even if the account wasn’t created.
answered Sep 11, 2015 at 19:45
Bart CalixtoBart Calixto
19.2k11 gold badges78 silver badges114 bronze badges
5
+1 to Barts answer — for security reasons. Usually I would agree that 409 is a good status code for sth. that already exists. But in an environment of user accounts/authentication/authorization etc., I would tend to not exposing the existing user accounts in your database.
Of course there are other mechanisms of handling security at this place. If you do not mind to expose a little number of your accounts, you could add a behavior to your application that returns 401 or 403 on numerous 409-events from one IP.
Another option (in general) is to define a status code on your own to have a 2xx that differs from the existing standard 2xx variants. This could be an option if you do not want to handle an «already exists» as an error. However, this would be regarded as non-standard and would have the same unsafe character like a 409 in your concrete example.
answered Sep 14, 2017 at 13:39
iquellisiquellis
9791 gold badge9 silver badges26 bronze badges
I often use the (WebDAV extension) HTTP 422 Unprocessable Entity:
The request was well-formed but was unable to be followed due to semantic errors
answered Feb 13, 2012 at 22:34
GarethGareth
133k36 gold badges148 silver badges157 bronze badges
1
409 => Conflict
That mean.
The request could not be completed due to a conflict.
For example, POST ContentStore Folder API cannot complete if the given file or folder name already exists in the parent location.
answered Jun 3, 2020 at 8:37
For registration it is required to have a code that is different from success 200 code, but not an error 4xx code.
As suggested in HTTP response code for POST when resource already exists look at 3XX:
302 Found
303 See Other
In particular
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.
The concern about exposure of existing addresses to enumerating bots can be addressed by different means such as captcha.
answered Oct 11, 2021 at 20:30
Michael FreidgeimMichael Freidgeim
26.6k16 gold badges152 silver badges172 bronze badges
0
У меня есть такая штуковина. Может, поможет.
Только не списывай точь в точь и поправляй что. У меня могут быть костыли, что не смогут у вас заработать. *^*
$sql = $mysqli->query("SELECT nicknames from table WHERE status = registered AND nicknames = {$nknm}")->num_rows; /* мы просто делаем запрос, что всё записывает в массивы 0, 1, 2... */
if ($mysqli->error) {
echo 'Произошла ошибка. Повторите запрос чуть позже.';
/* вывод ошибки. можно исключить, если уверенность в том, что ничего не сломается, есть */
} else {
if ($sql){
header ('Location: http://domen/registration_error.php ');
/* если запись есть, то мы об этом сообщаем. тут подставляй код, что тебе нужен или написал, ну или отсылай на страницу, как сделал я */
} else {
/* игнор будет работать, но только нужно будет сделать следующее:
$mysqli->query("alter table table add primary key (passwords);
alter table table add primary key (nicknames);
alter table table add primary key (status);");
или каждое по отдельности. */
$mysqli->query("INSERT IGNORE INTO table SET nicknames = {$nknm} AND status = registered AND passwords = {$pswd}");
if ($mysqli->error) {
header ('Location: http://domen/registration_error.php ');
} else {
/* тут код регистрации. он простой, просто всё записываешь в таблицу. */
print "Регистрация прошла успешно! Направляю на страницу входа..";
header('Refresh: 5; url=http://domen/login.php');
/* если же записи нет, то мы успешно регистрируем пользователя своим кодом, или примерно так, как я */
}
}
}
