Logo

Prolip's Blog

HTTP Method가 뭔데요 (2)
  • #Etc

HTTP Method가 뭔데요 (2)

Prolip

2024-05-05

공통 메서드 속성 알아보기... 안전한 메서드와 멱등성 메서드가 뭡니까?

시작..

지난 포스팅에선 RFC 문서의 HTTP Method 개요 부분을 정리해봤습니다..

이번 포스팅에선 그 이후의 내용인 공통 메서드 속성을 정리해보고자 합니다..

아마 메서드들이 가지는 특성에 대한 문서인듯한데 열심히 읽어봐야겠습니다.

1. Safe Methods

안전한 메서드

우선 안전한 메서드가 뭘까요? 문서에서 말하는 안전한 메서드는 클라이언트가 요청했을 때 서버의 상태를 변경하지 않는 메서드를 의미합니다.

즉, 클라이언트는 서버에 요청했을 때 서버의 데이터를 변경하지 않고 읽기만하는 본질적으로 읽기 전용인 메서드를 뜻합니다!

문서에 따르면 4가지 메서드를 안전하다고 정의하고 있습니다.

  • GET - 데이터를 조회할 때 사용됩니다.
  • HEAD - GET과 유사하지만, body (본문) 없이 헤더 정보만 요청합니다.
  • OPTIONS - 서버가 지원하는 메서드를 확인할 때 사용됩니다.
  • TRACE - 요청이 서버를 거쳐 어떻게 전달되는지 추적할 때 사용됩니다.

하지만 안전한 메서드라고 해도 간접적인 효과는 있을 수 있습니다. 하지만 이러한 효과는 클라이언트가 요청한 것이 아니기 때문에, 클라이언트는 책임을 지지 않습니다. 이를 부수적인 효과로 정의하고 있습니다.

문서에 나와있는 예시를 확인해보겠습니다.

  1. 로그 기록
    • 대부분의 서버는 모든 응답 완료 시점에 요청 정보를 로그 파일에 기록합니다. 이 때 로그 파일이 가득 차 서버가 실패할 가능성은 있지만, 클라이언트는 이를 책임 지지 않습니다.
  2. 광고 클릭
    • 사용자가 광고를 클릭해 서버에 요청을 보내면, 광고 계정에 요금이 부과될 수 있으나 이 또한 부수적인 효과로 클라이언트가 책임 지지 않습니다.

안전하지 않은 메서드

안전한 메서드와는 반대로 안전하지 않은 메서드는 서버의 상태를 변경할 가능성이 있는 메서드를 의미합니다. 클라이언트가 서버의 데이터를 생성, 수정, 삭제하는 등의 요청을 보낼 때 사용됩니다.

예로 POST, PUT, DELETE가 있겠군요.

안전하지 않은 메서드의 특징은 크게 2개로 정리할 수 있었습니다.

  1. 상태 변화 가능성: 서버의 상태를 변경할 수 있으며, 클라이언트는 이로 인한 부작용을 고려해야 합니다.
  2. 책임: 클라이언트가 이러한 요청을 보낼 때는 서버의 상태 변화에 대한 책임을 갖습니다.

구별하는 목적

그렇다면 굳이 안전한 메서드와 안전하지 않은 메서드를 구별하는 목적은 무엇일까요?

문서에선 자동화된 프로세스와 캐시를 효과적으로 사용하기 위함이라고 합니다.

그런데 이렇게만 얘기하면 잘 모르겠으니까 자동화된 프로세스와 캐시가 뭔지부터 알아보며 구별 목적을 알아봅시다.

1. 자동화된 프로세스

자동화된 프로세스는 사람의 직접적인 개입 없이 소프트웨어나 시스템이 자동으로 실행하는 작업을 의미합니다. 버거풋에서 사용된 웹 크롤러도 자동화된 프로세스겠군요..

검색 엔진에 사용되는 웹 크롤러는 페이지를 인덱싱하기 위해 서버에 많은 GET 요청을 보내게 됩니다. GET 요청은 안전한 메서드로 서버의 페이지를 인덱싱하지만 서버의 상태는 변경하지 않습니다.

만약 안전하지 않은 메서드(DELETE, PUT)를 사용하는데 잘못 설정된 경우 서버의 데이터가 의도치 않게 삭제되거나 변경될 수 있습니다.

2. 캐시

캐시는 자주 요청되는 데이터를 임시 저장하여, 동일한 요청이 반복될 때 원본 서버에 재요청하지 않고 임시 저장된 데이터를 빠르게 제공하는 시스템입니다. 캐시는 네트워크 대역폭 사용을 줄이고 응답 시간을 단축 시키며 서버 부하를 감소시키는 데 도움을 줍니다.

흠.. 그런데 왜 캐시에 대해 안전한 메서드를 사용하는 걸까요??

  1. 데이터 일관성 유지
  • 안전한 메서드 (GET, HEAD): 서버의 상태를 변경하지 않기 때문에 동일한 요청에 대해 항상 동일한 응답을 반환합니다. 따라서 캐시된 데이터를 제공해도 데이터 일관성이 유지됩니다.
  • 안전하지 않은 메서드 (POST, PUT, DELETE): 서버의 상태를 변경할 수 있기 때문에 캐시된 데이터를 사용하면 일관성이 깨질 수 있습니다. 예를 들어 PUT 요청을 통해 데이터를 수정 혹은 생성했는데 이 데이터를 캐시한다면 데이터 일관성이 깨질 수 있습니다.
  1. 효율적인 자원 사용
  • 안전한 메서드: 캐시된 데이터를 제공함으로써 반복적인 요청에서 서버의 리소스를 절약하고, 네트워크 대역폭 사용을 줄이며, 빠른 응답을 제공할 수 있습니다.
  • 안전하지 않은 메서드: 서버 상태를 변경하기 때문에 캐시된 응답을 제공하는 것이 아니라 항상 서버에서 새로 처리하므로 자원 절약과는 거리가 멀다고 볼 수 있습니다.

안전하지 않은 메서드를 제약하는 방법

  1. 사용자 에이전트의 역할

"A user agent SHOULD distinguish between safe and unsafe methods when presenting potential actions to a user, such that the user can be made aware of an unsafe action before it is requested.”

문서에선 사용자 에이전트는 사용자에게 잠재적인 동작을 제시할 때 안전한 메서드와 안전하지 않은 메서드를 구분해야 하며, 사용자가 요청하기 전에 안전하지 않은 동작을 인지할 수 있도록 해야한다고 합니다. 그런데 SHOULD.. 즉 권고 사항이라고는 합니다.

사용자 에이전트는 컴퓨터 프로그램이나 소프트웨어로, 사용자 대신 네트워크 서비스에 접속하는 역할을 합니다. 사용자 대신 HTTP 요청을 서버에 보내고, 서버로부터 받은 응답을 처리해 사용자에게 보여준다고 생각하시면 됩니다.

문서의 내용상 웹 브라우저 (Chrome, Firefox, Edge)를 의미하지만, 넓은 의미로는 다양한 형태의 클라이언트 프로그램을 포함할 수 있습니다.

즉, 사용자 에이전트는 안전하지 않은 메서드를 사용할 때 사용자에게 이를 알리고 확인을 받도록 함으로써 사용자가 의도치 않게 서버의 상태를 변경하는 것을 방지해야 한다는 내용입니다.

예를 들어 브라우저는 폼 제출 시 사용자가 데이터를 변경할 의도가 있는지 확인하는 절차를 통해 의도하지 않은 데이터 변경을 방지하도록 제약하는 방법이 있습니다.

  1. 리소스 소유자의 책임

일반적인 웹사이트에서 쿼리 파라미터를 사용해 특정 동작을 수행할 수 있습니다.

그렇다면 리소스 소유자는 서버의 URI가 안전하지 않은 동작을 수행하지 않도록 보장해야 합니다. 이는 주로 서버 측 코드와 설정을 통해 이루어집니다.

  • 동작의 일관성 보장
    • 리소스가 생성될 때, URI 내의 매개변수가 동작을 선택하는 효과를 가질 수 있습니다. 예를 들어 ‘page?do=delete’와 같은 URI가 있다면, 이 URI가 GET 요청으로 데이터를 삭제하지 않도록 해야 합니다.
    • 필수 사항: 리소스 소유자는 안전한 요청 메서드를 사용할 때, 안전하지 않은 동작을 비활성화하거나 혀용하지 않아야 합니다. 이를 준수하지 않으면 자동화된 프로세스가 각 URI 참조에 대해 GET 요청을 수행하는 과정에서 서버에 부정적인 영향을 미칠 수 있기 때문입니다. 문서에선 해당 내용을 필수 사항(MUST)으로 강조하고 있습니다.
  • 적절한 메서드 사용
    • 서버의 상태를 변경하는 작업은 반드시 적절한 HTTP 메서드를 사용해 수행해야만 합니다. 예를 들어, 데이터를 삭제할 때는 DELETE 메서드를 사용해야만 합니다.

2. Idempotent Methods

멱등성 메서드 (Iempotent Methods)

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

요청 메서드는 동일한 메서드로 여러 개의 동일한 요청을 했을 때 서버에 대한 의도된 효과가 단일 요청과 동일한 경우 “멱등”하다고 간주됩니다.

우선 멱등성이란 동일한 요청을 여러 번 보냈을 때 서버에 미치는 최종적인 영향이 한 번 보냈을 때와 동일한 속성을 의미합니다.

즉, 여러 번 동일한 요청을 보내도 서버의 상태는 한 번 요청한 것과 동일하게 유지됩니다.

  • PUT: 특정 리소스를 생성하거나 대체하는 요청으로 동일한 데이터를 여러 번 보내더라도 리소스의 상태는 동일하게 유지되므로 멱등성을 가집니다.
  • DELETE: 특정 리소스를 삭제하는 요청으로 동일한 리소스를 여러 번 삭제 요청해도 결국 리소스는 삭제된 상태로 유지되므로 멱등성을 가집니다.
  • 안전한 메서드: GET, HEAD, OPTIONS, TRACE 등은 서버의 상태를 변경하지 않기 때문에 멱등성을 가집니다.

멱등성 메서드의 특징

  1. 의도된 효과의 일관성
  • 여러 번 동일한 요청을 보내더라도 서버의 최종 상태는 동일합니다.
  • 예를 들어, PUT 요청으로 리소스를 업데이트할 때 동일한 요청을 여러 번 보내더라도 리소스는 동일한 상태를 유지합니다.
  1. 자동 재시도 가능성
  • 클라이언트는 서버의 응답을 받기 전에 통신 실패가 발생한 경우 요청을 자동으로 반복할 수 있습니다.
  • 예를 들어, 클라이언트가 PUT 요청을 보낸 후 연결이 끊어지면, 클라이언트는 새로운 연결을 설정하고 요청을 다시 시도할 수 있습니다.
  1. 부작용 없는 반복 가능
  • 각 요청을 별도로 기록하거나 로그를 남기거나, 수정 기록을 유지하는 것과 같은 부수적인 효과는 있을 수 있습니다.
  • 그러나 이러한 부수적인 효과는 클라이언트가 의도한 것이 아니며, 클라이언트가 책임지지 않습니다.

예를 들어…

PUT 요청의 멱등성

PUT /posts/411 HTTP/1.1
Host: www.gojimin.com
Content-type: application/json

{
	"title": "제목",
	"description": "내용"
}
  • 첫 번째 요청: 포스트 411이 해당 데이터로 업데이트됩니다.
  • 두 번째 요청: 동일한 포스트 411이 다시 동일한 데이터로 업데이트됩니다.
  • 최종 상태: 포스트 411의 상태는 동일합니다.

DELETE 요청의 멱등성

DELETE /posts/411 HTTP/1.1
Host: www.gojimin.com
  • 첫 번째 요청: 포스트 411이 삭제됩니다.
  • 두 번째 요청: 포스트 411이 이미 삭제된 상태입니다.
  • 최종 상태: 포스트 411은 삭제된 상태로 유지됩니다.

그렇다면..

클라이언트는 멱등성 메서드를 사용한 통신이 실패한다면 요청을 자동으로 반복할 수 있습니다. 이는 멱등성 메서드가 여러 번 호출되더라도 최종 상태가 동일하다는 것을 보장하기 때문에 가능한 것입니다.

예를 들어 클라이언트가 PUT 요청을 보냈으나 응답을 받기 전에 연결이 끊어졌을 경우, 클라이언트는 동일한 요청을 다시 보내 최종 상태를 일관되게 유지할 수 있습니다.

하지만 멱등성이 아닌 메서드인 POST의 경우 동일한 POST 요청을 여러 번 보내면 데이터가 중복으로 저장되거나 변경되는 등 서버의 상태가 변경될 수 있습니다.

요약하자면

  • 멱등성 메서드는 동일한 요청을 여러 번 보내더라도 서버의 최종 상태가 한 번 보냈을 때와 동일하게 유지되는 요청 메서드입니다.
  • 멱등성 메서드는 통신 실패 시 요청을 자동으로 반복할 수 있습니다.
  • 각 요청이 로그에 기록되는 등의 부수적인 효과는 있을 수 있지만, 클라이언트가 의도한 것이 아니므로 클라이언트는 이에 대해 책임지지 않습니다.
  • 안전한 메서드는 서버의 상태를 변경하지 않으므로 멱등성을 갖습니다.
    • GET, HEAD, OPTIONS, TRACE
  • 안전하지 않은 메서드는 서버의 상태를 변경할 수 있으며, 멱등성을 가질 수도 있고 가지지 않을 수도 있습니다.
    • 멱등성: PUT, DELETE
    • 비멱등성: POST

3. Methods and Caching

캐싱은 서버 응답을 저장하고 이후에 동일한 요청이 있을 때 저장된 응답을 재사용함으로써 서버 부하를 줄이고 응답 시간을 단축시키는 기술입니다.

캐싱 가능한 메서드

HTTP 메서드 중에서 캐싱을 명시적으로 혀용하는 메서드만이 캐시될 수 있습니다. 캐시가 응답을 저장하고 사용할 수 있으려면 해당 메서드가 캐싱 조건을 명시해야합니다.

  1. GET
    • GET 메서드는 리소스를 요청해 해당 리소스의 표현을 반환합니다.
    • GET 요쳥의 응답은 캐시될 수 있습니다.
  2. HEAD
    • HEAD 메서드는 GET과 유사하지만, 응답 본문을 포함하지 않고 헤더 정보만 반환합니다.
    • HEAD 요청의 응답도 캐시될 수 있으며, 해당 응답은 GET 요청의 응답을 검증하는 데 사용할 수 있습니다.
  3. POST
    • POST 메서드는 서버에 데이터를 제출하여 리소스를 생성하거나 수정합니다.
    • POST 요청의 응답도 캐시될 수 있지만, 이는 명시적인 캐시 제어 헤더가 있을 때만 가능합니다. 대부분의 캐시 구현은 POST 요청의 캐싱을 지원하지 않습니다.

캐싱 조건

캐시가 응답을 저장하고 사용할 수 있으려면 다음 조건을 충족해야 합니다.

1. 명시적 캐시 허용

응답에 ‘Cache-Control’ 헤더나 ‘Expires’ 헤더와 같은 캐시 제어 지시자가 있어야 합니다.

Cache-Control 헤더

  • ‘Cache-Control’ 헤더는 응답이 어떻게 캐시되어야 하는지를 명시합니다.
  • 주요 지시자는 다음과 같습니다.
    • ‘max-age=<seconds>: 응답이 캐시될 수 있는 최대 시간을 초 단위로 지정합니다.
    • ‘no-cache’: 응답이 캐시될 수 있지만, 사용하기 전에 서버에 다시 검증해야 합니다.
    • ‘no-store’: 응답이 캐시되지 않도록 설정합니다.
    • ‘public’: 응답이 모든 캐시(브라우저와 중간 캐시를 포함)에 의해 캐시될 수 있음을 나타냅니다.
    • ‘private’: 응답이 특정 사용자에 의해 사용되는 캐시에만 저장될 수 있음을 나타냅니다.
  • 예시 (Cache-Control): 해당 예시는 응답이 3600초 동안 캐시될 수 있음을 나타냅니다. 그 동안 동일한 요청이 있을 경우 캐시된 응답이 사용됩니다.
HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Type: text/html

<html>...</html>

Expires 헤더

  • ‘Expires’ 헤더는 응답이 만료되는 날짜와 시간을 HTTP 날짜 형식으로 지정합니다.
  • 예시 (Expires): 해당 예시는 응답이 2024년 9월 12일(제 생일 ㅋ) 오후 8시 21분까지 캐시될 수 있음을 나타냅니다. 이 시간이 지나면 응답은 더 이상 유효하지 않습니다.
HTTP/1.1 200 OK
Expires: Thu, 12 Sep 2024 11:21:00 GMT
Content-Type: text/html

<html>...</html>

2. 조건부 요청

‘ETag’ 또는 ‘Last-Modified’ 와 같은 조건부 요청 헤더를 사용하여 캐시된 응답의 유효성을 검증할 수 있어야 합니다.

ETag 헤더

  • ‘ETag’ 헤더는 리소스의 특정 버전을 나타내는 고유한 식별자를 제공합니다. 이 식별자를 사용하여 서버에 조건부 요청을 보낼 수 있습니다.
  • 예시 (ETag): 해당 응답은 **‘etag0912’**라는 ETag 값을 가집니다. 클라이언트는 이 값을 사용하여 리소스가 변경되었는지 확인할 수 있습니다.
HTTP/1.1 200 OK
ETag: "etag0912"
Content-type: text/html

<html>...</html>
  • 조건부 요청 예시 (If-None-Match): 클라이언트는 ‘If-None-Match' 헤더를 사용하여 서버에 조건부 요청을 보냅니다. 서버는 ETag 값이 동일하면 ‘304 Not Modified’ 상태 코드로 응답하여 클라이언트가 캐시된 데이터를 사용할 수 있도록 합니다.
GET /jimin-page HTTP/1.1
Host: www.gojimin.com
If-None-Match: "etag0912"

Last-Modified 헤더

  • ‘Last-Modified’ 헤더는 리소스가 마지막으로 수정된 날짜와 시간을 제공합니다.
  • 예시 (Last-Modified): 이 응답은 리소스가 2024년 6월 26일 06:28:05 GMT에 마지막으로 수정되었음을 나타냅니다.
HTTP/1.1 200 OK
Last-Modified: Wed, 26 Jun 2024 06:28:05 GMT
Content-Type: text/html

<html>...</html>
  • 조건부 요청 예시: 클라이언트는 ‘If-Modified-Since’ 헤더를 사용하여 서버에 조건부 요청을 보냅니다. 서버는 리소스가 그 이후로 변경되지 않았다면 ‘304 Not Modified’ 상태 코드로 응답하여 클라이언트가 캐시된 데이터를 사용할 수 있도록 합니다.
GET /jimin-page HTTP/1.1
Host: www.gojimin.com
If-Modified-Since: Wed, 26 Jun 2024 06:28:05 GMT

요약하자면..

  • Cache-Control은.. 응답이 어떻게 캐시되어야 하는지를 지정하는 헤더입니다.
  • Expires는.. 응답이 만료되는 날짜와 시간을 지정하는 헤더입니다.
  • ETag는.. 리소스의 특정 버전을 식별하는 고유한 식별자입니다. 조건부 요청에서 사용됩니다.
  • Last-Modified는.. 리소스가 마지막으로 수정된 날짜와 시간을 나타내는 헤더입니다. 마찬가지로 조건부 요청에서 사용됩니다.

오늘은 여기까지!

이번 포스팅에선 공통 메서드 속성에 대해 정리해봤습니다. 원래 메서드 정의까지 여기서 다 정리해보려고 했는데 또 끝없이 길어질 거 같아서 여기서 끊어가려고 합니다..

읽어주셔서 감사합니다..

.

.

뿅..

HTTP Method가 뭔데요 (1)

HTTP Method가 뭔데요 (1)

HTTP Method가 뭔데요 (3)

HTTP Method가 뭔데요 (3)