API에서 유효성 검증은 어떤 status로 응답해야할까
API 개발을 하다 보면 클라이언트 요청을 어떻게 처리할지, 특히 실패했을 때 어떤 HTTP 상태 코드를 반환할지 고민할 때가 많다.
현재는 대부분이 400
으로 응답하고 있다.
이번에 여러 상황을 정리해보면서 어떤 코드를 써야 하는지 생각해봤다.
1. 필수 파라미터가 없을 때
API 호출할 때 필수 값이 빠졌다. (ex. Id
)
서버에서 이걸 검증하고 걸러낸다면?
이건 클라이언트가 잘못 보낸 요청이다. API 문제라기보다는, 잘못된 요청을 서버가 빠르게 걸러낸 것.
이렇게 잘못된 요청 파라미터로 인해 서버가 요청을 처리할 수 없는 경우.
400 Bad Request 이 적절하다고 생각한다.
2. 비즈니스 로직에서 막히는 경우
요청은 잘 왔는데, 서버 비즈니스 로직 상 허용할 수 없는 경우다. 아마도 가장 빈번한 케이스!
(ex. 비밀번호 변경 API에서 “최근 3회 사용한 비밀번호는 안 된다” 같은 규칙.)
이건 두 가지로 나눠볼 수 있다.
-
403 Forbidden
규칙상 금지된 행위 (ex: 그 비밀번호는 사용 금지) -
409 Conflict
현재 상태와 충돌 발생 (ex: 비밀번호가 과거 기록과 충돌)
권한 문제로 보면 403, 상태 충돌로 보면 409를 쓰는 게 적절해보인다. 이건 생각하기 나름인듯하다.
3. 데이터 중복
저장 요청에서 데이터가 중복인 경우로 요청은 문제없지만, 서버 상태와 충돌이 발생한 경우다.
예를들면 아래 같은 경우다.
- 중복된 username, email, ID
- optimistic locking에서 버전 충돌
GPT느 409 Conflict 를 사용하라고 한다.
데이터 중복은 현재 상태와 충돌로 보는듯하다.
정리해보자
상황 | 추천 HTTP Status |
---|---|
잘못된 요청 파라미터, 누락 | 400 Bad Request |
비즈니스 규칙 위반 | 403 Forbidden 또는 409 Conflict |
중복 데이터 (예: 이메일 중복) | 409 Conflict |
혼자 작업하는게 아니고 상태값에 대한 서로의 의견도 조금씩은 달라서 참 어렵다.
상태값을 고를 땐
- 문제의 원인이 클라이언트 쪽인가, 서버 쪽인가?
- 어떤 종류의 오류인가?
이걸 잘 구분해야 한다.
괜히 500 같은 서버 에러로 잘못 응답하면, 클라이언트는 API가 고장난 줄 오해할 수 있다.