회원가입을 만들다가 갑자기 궁금한 생각이 들었다.(처음 만들어 보는 것도 아닌데!!) 회원가입을 하려고 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를 쓰기로 했다. 여러 가지를 비교해 본 결과 가장 적합하다고 생각해서...(스펙은 항상 어렵;;)
POST 요청전에 AJAX 로 중복을 확인해주는게 좋지 않을지요?
뭐 따로 중복체크 button 을 만들어서 체크하기 보단, 그냥 sign up 눌렀을때 확인해주고 중복이 아니면 바로 가입절차 들어가고, 중복이라면 중복이라고 알려주는 식으로... (On change event 에서 바로 확인할수 있기도. 이렇게 구현해놓은 사이트들도 꽤 있었던거 같구요.)
그런데 status code 따라서 브라우저가 따로 처리해 주는게 있나요? 그냥 규칙인거죠?
AJAX로 체크해도 동일한 이슈입니다. 확인 API에서 중복안되면 200 OK지만 중복되면 응답코드가 어떤가 하는 부분이지요. 브라우저는 5XX 같은 경우는 브라우저가 따로 보여주기도 하죠.
역시 논란의 여지가 많은 부분이죠 :)
정리해주셔서 감사합니다.
깔끔히 정리되지 않아도 고민해 볼때 흥미로운 이슈들이죠 ㅎㅎ
저도 초기에 잠깐 고민하다가 409 Conflict를 쓰는데 반가운 포스팅입니다 ㅎㅎ
같은 고민을 하셨다니 저도 반갑네요 ㅎ
저희 서버에서도 이미 가입된 이메일로 회원가입 시도시 409 충돌 에러를 보여주고 있습니다. :)