Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

회원가입 시 이메일/아이디가 중복될 때의 응답 HTTP status code

회원가입을 만들다가 갑자기 궁금한 생각이 들었다.(처음 만들어 보는 것도 아닌데!!) 회원가입을 하려고 POST 요청을 보냈는데 이메일이 겹치거나 아이디가 겹칠 경우 서버의 응답 상태코드는 무엇이 되어야 하는가? 물론 스펙을 떠나서 200 OK로 응답을 주고 응답 보디에서 결과를 보내주는 방법도 현실적으로는 가능한 방법이지만 이건 또 다른 주제의 내용이므로 여기서는 스펙을 따른다고 했을 때를 전제로 한다.

400 Bad Request

처음에는 400 Bad Request로 구현을 했다.

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
-RFC 2616

RFC 2616에 따르면 위와 같이 정의가 되어 있다. 요청에서 지켜야 할 문법을 제대로 지키지 못해서 서버가 이해를 못 했기 때문에 튕겨낸다는 것인데 회원 가입 같은 경우는 곰곰이 생각해 보면 이 상황에 어울려 보지는 않는다. 회원가입 같은 경우 요청은 정상적이고 클라이언트 입장에서는 요청을 보내기 전에는 알 수 없는 상태이기 때문이다.

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).
- RFC 7231

하지만 RFC 2616의 개정판인 RFC 7231에서는 400 Bad Request의 의미가 좀 더 광범위해서 서버가 처리 못 하는 것뿐 아니라 어떤 오류로 처리하지 않는 부분에도 400을 쓸 수 있다고 정의하고 있다.(스펙의 해석은 어려운 부분이긴 하지만..) 그래서 스펙대로라면 이제(RFC 7231에서 개정되었으므로) 400도 사용 가능하다고 생각한다.

409 Conflict

상태코드에는 409 Conflict코드도 존재한다.

The request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request. The server SHOULD generate a payload that includes enough information for a user to recognize the source of the conflict.
-RFC 7231

리소스의 현재 상태와 충돌해서 요청을 처리할 수 없으므로 클라이언트가 요청을 다시 클라이언트가 이 충돌을 수정해서 요청을 다시 보낼 경우가 Conflict다.(RFC 2616과 큰 차이는 없다.) 내가 이해하기에는 지금의 상황에 가장 적합하게 느껴진다.

403 Forbidden

관련해서 찾다 보니 유효성 검증 실패에는 403을 써야 한다는 의견도 있었다. 보통 403이 인가(Authroization) 실패로 생각하지만, RFC 2616에는 그렇게 명시하고 있지 않으므로 403이 적합하다는 말이다.(이메일이나 아이디 중복도 유효성 검사의 과정이긴 하지만 여기서는 비밀번호나 아이디 자릿수나 허용 문자 등의 유효성 검증에 더 가까워 보인다.)

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.
-RFC 2616

하지만 RFC 7231에서는 사람들이 일반적으로 생각하는 대로 인가에 사용하도록 명시하고 있으므로 이제는 이견의 여지는 없어 보인다.

The server understood the request but refuses to authorize it. A server that wishes to make public why the request has been forbidden can describe that reason in the response payload (if any).
- RFC 7231



이래저래 고민하다가 나는 409 Conflict를 쓰기로 했다. 여러 가지를 비교해 본 결과 가장 적합하다고 생각해서...(스펙은 항상 어렵;;)

2015/01/31 19:37 2015/01/31 19:37