HTTP 상태 코드 살펴보기
포스트
취소

HTTP 상태 코드 살펴보기

학원 최종 프로젝트였던 project-Betty 가 끝났다.
시간에 쫒겨 공통 예외 처리를 구현하지 못했었는데
결과적으로 상태 코드에 대한 학습이 우선이라 생각됐다.


정리하려는 이유는 아래와 같다.


클라이언트 측의 예외 인지

1
2
3
4
5
6
7
8
9
10
11
12
13
서버에서 Exception 이 발생하면,
 ajax 문 내부 error 에 정의된 콜백 함수가 실행되길 바랬다.

요청에 대한 정상적인 응답이 아님에도 200(OK) 코드로 전송되어
 success 내부에서 약속에 의한 코드 또는 메시지로 분기하는 건, 
 ajax 를 정의한 개발자에 대한 예의가 아니라 느꼈다.
 (애초에 전 지구적 약속인 Http 상태 코드가 존재한다.)

확실하진 않으나 서버에서 발생한 Exception 에 상태코드를 따로 붙여주지 않는다면
 톰캣이 멋대로 200 코드로 넘긴다고 알고 있다.

클라이언트 - 서버 구조에서 좀더 우아하게 Http 프로토콜을 다루려면
 상태코드에 대한 학습이 필요하다고 생각한다.


아래의 코드는 “org.springframework.http” 패키지의 HttpStatus 클래스에 정의된 목록 중 일부이다.




3xx 리다이렉트


  • MOVED_PERMANENTLY(301, “Moved Permanently”)

  • FOUND(302, “Found”)

  • TEMPORARY_REDIRECT(307, “Temporary Redirect”)

  • PERMANENT_REDIRECT(308, “Permanent Redirect”)


   정리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
요청 경로와 다른 URL로의 이동에 대해 몇 가지 생각나는 게 있다.
1. 요청한 페이지가 영구적으로 사라졌다.
2. 요청한 페이지가 단기간 다른 페이지로 전환됐다.
3. 권한 불충분으로 인해 접근이 거부되었다.
4. Rest 방식에서의 URL 은 대게 리소스의 고유 값이 들어가는 데, 
 이 때의 비정상 접근

1,2 번은 정상적인 리다이렉션이지만
3,4 번은 비정상 접근에 대한 리다이렉션이므로 
 4xx 에러에서 다루는 게 맞는 듯하다.

[301], [308] : moved permanently, permanent redirect
    영구적인 페이지 이동은 301, 308 로 해결할 수 있을 것 같다.
    하지만 내 눈엔 동일해보여 둘 중 누구를 선택할 지는 모르겠다.
    물론 3xx 코드를 사용하는 경우, Exception 과 연관지을 생각은 없다.

[302] : found
     location.href 등 단순 링크이동, 
    흔한 response.sendRedirect 의 결과이다.
    직접 사용할 일은 없어보인다.

[307] : temporary redirect
    이벤트 또는 점검 중에 활용할 수 있을 것 같다.

전체적으로 Http Header 를 Exception 관련 없이 다룰테니 
 ResponseEntity 를 사용하는 방법이 떠오른다.



4xx 클라이언트 에러


  • BAD_REQUEST(400, “Bad Request”)

  • UNAUTHORIZED(401, “Unauthorized”)

  • FORBIDDEN(403, “Forbidden”)

  • NOT_FOUND(404, “Not Found”)

  • METHOD_NOT_ALLOWED(405, “Method Not Allowed”)

  • NOT_ACCEPTABLE(406, “Not Acceptable”)

  • REQUEST_TIMEOUT(408, “Request Timeout”)

  • UNSUPPORTED_MEDIA_TYPE(415, “Unsupported Media Type”)

  • I_AM_A_TEAPOT(418, “I’m a teapot”)

  • UNAVAILABLE_FOR_LEGAL_REASONS(451, “Unavailable For Legal Reasons”)


   정리

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
클라이언트 에러를 정리해보기 전에, 
 우선 서버 에러 코드(5xx)를 발생시키지 않는 게 
 나의 명줄과 직결된 사항이라 생각한다. 

가능한 예외는 모두 클라이언트의 몫이어야 된다.
그리하여 4xx 에러는 상태 코드를 정리하려는 목적 중 핵심이다.


[400] : bad request
    잘못된 요청이라하면 어떤 게 있을까? 
    400번이 4xx 의 부모격이고 나머지는 400을 상속한 코드들로 보인다.


[401] : unauthorized
    비인가. 권한 불충분일 때, 
    아마 잘 막아놨다면 이는 악의적인 접근일 확률이 높다.


[403] : forbidden
    금지됐다하면.. 사실 비슷비슷해보이지만 
    계정 권환과 상관없이 URL을 조작하여
    UI상 나타나지 않은 이벤트(?)를 발생시키려할 때 사용할 수 있을 것 같다.

    하지만 서버에서 이를 인지하려면 현재 URL 정보를 인지하고 
    예외에 대한 핸들링을 해야하는데 구현하기엔 쉽지 않을 듯하다.


[404] : not found
    PAGE NOT FOUND 즉, 매핑된 핸들러가 없는 경로 
    또는 공통 리소스에 접근했으나 영속 계층에 데이터가 
    존재하지 않는 상황에 던질 수 있다.


[405] : method not allowed
    메소드가 허용되지 않은 상황이 어떤 게 있을까.
    Validation 을 적용하였으나 바인딩 에러가 
    나타난 상황에 사용할 수 있을 것 같다.

    다른 상황은 정말 모르겠다.
    굳이 엮자면 IllegalArgumentsException 과 엮어, 
    결괏값과 무관하게 서비스단 호출부터 
    비정상적으로 이루어지는 상황에 사용하자.


[406] : not acceptable
    Betty 프로젝트를 진행하며 계정과 권한 관련하여 시큐리티 없이 
    되게 신경써서 작업했는데 권한 관련 접근 제어는 
    이 상태 코드를 이용하면 됐을 것 같다.

    우린 Rest 방식의 URL 에 회원 id 자체를 넣게 되었는데, 
    이건 딱히 좋지 않은 것 같다.

    데이터베이스에서 기본 키 자체를 id로 지정하여 달리 방법이 없었다.
    아무튼 사용자는 다른 계정의 개인 페이지 접근에 대해 
    호기심을 품을 수 밖에 없을 테다.

    세션과 uri 비교로 막긴 했으나, 좀더 깔끔하게 처리하려면 
    406 코드를 사용했으면 좋았겠다.


[408] : request timeout
    요청 시간 초과는 서버에서 핸들링 할 수 있을까? 
    그것도 사용자 문제로 돌릴려면,
    문자나 이메일 인증에 대한 시간 초과를 이 코드로 해결할 수 있겠다.
    
    나의 경우는 두 인증에 대한 코드를 세션에 저장하고 세션 유지 시간을  
    3분으로 잡았다.

    클라이언트가 인증 코드를 전송했으나 3분이 지난 경우, 
    즉 세션이 사라졌을 때, 408 코드를 던질 수 있겠다.


[415] : unsupported media type
    그대로 사용하면 될 것 같다. 필요한 영역이 확실해보인다.


[418] : i am a teapot
    이건 궁금해서 놔뒀다. 뭘까?


[451] : unavailable for legal reasons
    나쁜 이유로 불허? 
    이건 사실 400이나 다른 코드로 처리하면 될 것 같다.
    언젠가 쓸모가 있기에 있는 게 아닐까 싶다. 



5xx 서버 에러


  • INTERNAL_SERVER_ERROR(500, “Internal Server Error”)

  • BAD_GATEWAY(502, “Bad Gateway”)

  • SERVICE_UNAVAILABLE(503, “Service Unavailable”)

  • GATEWAY_TIMEOUT(504, “Gateway Timeout”)

  • INSUFFICIENT_STORAGE(507, “Insufficient Storage”)

  • NETWORK_AUTHENTICATION_REQUIRED(511, “Network Authentication Required”)



   정리

1
2
3
5xx 코드를 자랑스럽게 반환할 상황이 있을까?
이걸 정리하려는 것조차 자존심이 상한다.
코드를 잘 짜고 서버는 수평 확장이 가능해야되지 않을까?




총정리

공통 예외 처리에 대한 고민으로 시작된 상태 코드 정리에 너무 몰입해버렸다.
적는 도중에 스스로 느낀 건데, 상태 코드 = Exception 라는 생각이 어느새 박혀있었다.
내가 상태코드를 정리한 이유는,
ajax 에게 예외를 인지시키기 위해 Http 에 얹을 코드를 찾기 위함이고,


지금 내게 상태 코드란,
서버에서 어떤 일이 일어났는가,
클라이언트의 요청을 서버는 어떻게 받아들였는가.

여기에 대한 약속이라 여겨진다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.