인프런 커뮤니티 질문&답변

suhani93님의 프로필 이미지
suhani93

작성한 질문수

모든 개발자를 위한 HTTP 웹 기본 지식

4xx - 클라이언트 오류, 5xx - 서버 오류

5XX 관련 질문있습니다.

작성

·

1K

35

안녕하세요
강의 중 20살 이상인 경우에 통과하는 로직이 있는데 15살이 들어온 경우 5XX 가 아닌 다른 에러를 출력하라고 하신 부분에 대한 질문입니다.

위와 같은 경우에는 400 Bad Request 에러를 내야 하는 건가요 ??

아니면 다른 대안이 있을까요??

답변 5

83

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. suhani93님

여기서 먼저 5xx를 제외한 선택지가 400이나 200으로 처리해야 하는데요.

클라이언트와 서버가 서로 API 스펙을 맞출 때 만약 나이는 20살 이하로 넘기면 안됩니다. 라고 HTTP API 스펙에 정의를 했으면 400으로 응답을 반환하는 것이 맞습니다. 이것은 명확하게 클라이언트가 서로간의 약속을 지키지 않은 것이지요. 클라이언트는 검증 로직을 만들어서 20살 이하면 서버로 요청이 넘어가지 못하게 막아야 합니다.

그런데 실무에서 개발을 해보면 항상 이렇게 단순하게 문제가 끝나지는 않습니다.

클라이언트가 서버가 요구하는 스펙을 다 지켰을 때 발생하는 비즈니스 예외들을 어떻게 처리할까 하는 것이지요.

지금부터 말씀드리는 내용은 정답이라기 보다는 제가 개인적으로 선호하는 방식을 설명드리겠습니다.

예를 들어서 회원 가입을 신청할 때 연령과 관계없이 가입 신청을 받아야 하는데, 일반적인 경우는 바로 회원 가입이 되지만, 20살 이하인 경우는 내부 심사를 위해서 보류 상태로 반환해야 할 때, 어떻게 응답해야 하는가?

비슷한 시나리오로 보험금을 지급해 달라고 서버에 요청했는데 HTTP API 스펙의 요청은 모두 만족했지만, 비즈니스 로직상 이 사람이 요건을 모두 충족하지 못해서 지급이 승인 거절되는 경우에는 어떻게 응답해야 하는가?

이런 경우처럼 클라이언트의 요청에서 서로 약속한 HTTP API 스펙은 만족했지만, 그래서 비즈니스 로직까지 정상 수행했지만, 비즈니스 로직의 결과가 성공으로 처리되지 않을 수 있습니다. 이런 경우 400을 반환하게 되면, 클라이언트 개발자는 분명 서로 약속한 API 스펙을 다 지켰는데, 클라이언트 개발자에게 잘못 개발하셨어요. 라고 이야기하는 것과 같습니다.

그래서 이렇게 복잡한 비즈니스 로직이 들어가는 경우 200 OK로 응답하면서 결과에 내부 비즈니스 응답 코드를 정의해서 함께 전달합니다. 다음과 같이 응답 코드를 만들고 데이터도 한번 감싸서 전달하는 것이지요. 이것을 봉투 패턴(Envelope pattern)이라 합니다.

봉투가 포함된 응답

{

  "code": "success" ("success", "fail", "hold", "deny" ...)

  "data": {memberId: ... 결과 데이터}...

}

제가 선호하는 방식은 200 OK 라는 응답은 HTTP API 스펙상 요청이 성공해서 비즈니스 로직을 정상적으로 실행하는 단계까지 전달된 것으로 기준을 잡습니다. 결과적으로 HTTP 200 응답 코드는 비즈니스 로직의 내부 결과와는 무관하게 클라이언트와 서버간에 요청과 응답이 정상수행되었는지를 기준으로 잡습니다. HTTP 표준 스펙이 응답코드에 세상의 모든 비즈니스 로직까지 다 담을 수는 없으니까요.

물론 비즈니스 로직을 수행하다가 데이터베이스 접속이 안되거나 NullPointerException등이 발생하면, 이것은 500으로 응답을 하는 것이 맞습니다.

그런데 항상 이렇게 감싸면(이렇게 감싸는 것을 봉투 패턴(Envelope pattern) 이라 합니다.) 응답 구조가 너무 복잡해질 수 있습니다. 그래서 단순히 데이터만 조회하고, 크게 비즈니스 로직이 없는 경우에는 봉투 없이 단순하게 개발하는 것이 좋습니다.(특히 단순한 조회)

봉투 없는 단순한 응답

{

  memberId: ...

  username: ...

}

정리하면 다음과 같습니다.

1. 서로 약속한 HTTP API 스펙을 만족한다. -> 200, 만족하지 않는다. -> 400

2. 비즈니스 로직이 정상 수행되지만, 다양한 결과가 존재한다.(승인, 거절 등등) -> 200 + 비즈니스 코드 반환(봉투 패턴)

3. 비즈니스 로직을 수행하다가 내부에서 시스템 예외나 NullPointerException 등등 비즈니스와 관계없는 시스템 예외가 발생한다. -> 500

참고: 다양한 비즈니스 응답이 있는 복잡한 비즈니스 로직이 있는 HTTP API는 봉투 패턴을 고려하고, 비즈니스 로직이 거의 없는 단순한 조회에서는 봉투 패턴을 고려하지 않는다.

앞서 말씀드린 것 처럼 이것이 딱 정답이라기 보다는 제 경험에서 나온 부분이 많아서, 이것을 참고로 본인의 비즈니스에 맞는 HTTP API 스펙을 고민해보시면 좋겠습니다.

도움이 되셨길 바래요^^

이해가 잘갑니다. 가려운 부분 시원하게 긁고 갑니다.

3

suhani93님의 프로필 이미지
suhani93
질문자

정말 자세한 답변 감사드립니다.

0

너무 좋은 답변 감사합니다!

0

저도 질문하러 왔다가 좋은 정보 얻고 갑니다.

감사합니다

0

와우 현재 실무에서 많이 고민하던 부분인데 이런 패턴을 봉투패턴이라고 하는군요!

이 질문 하려왔다가 해답을 얻고 갑니다 :)

suhani93님의 프로필 이미지
suhani93

작성한 질문수

질문하기