HTTP Method(with 안전성, 멱등성)

Server_side·2024년 2월 8일
1
post-custom-banner

서론

HTTP Method 중 GET / POST / PUT / PATCH / DELETE가 주로 사용되며 HTTP Method의 동작과정, 속성 등을 명확히 알고 사용해야 올바른 설계라고 할 수 있다.
아래 표에서 HTTP Method의 몇가지 대표 속성을 확인할 수 있으며 본문에서 각 속성에 대해 조금 더 알아보자

HTTP Method안전성멱등성
GETOO
POSTXX
PUTXO
PATCHXX
DELETEXO

안전성(Safe)

HTTP Method에서의 안전성이란 해당 Method를 호출해도 데이터가 변하지 않는 것을 말한다.
GET의 경우, 리소스를 수정하지 않고 단순히 조회만 하는 기능을 가지므로 안전성 측면에서 안전하다고 할 수 있다.
그러나, POST, PUT, PATCH, DELETE의 경우 데이터를 추가/수정/삭제하게 되므로 안전성 측면에서 안전하다고 볼 수 없다.

멱등성(Idempotent)

HTTP Method에서의 멱등성이란 동일한 요청에 대해 한 번 요청하든 여러 번 요청하든 서버에 미치는 영향이 동일한 것을 말한다.
멱등성은 결제와 같이 중복되어 수행되면 큰 문제가 발생할 수 있는 상황에서 필수적이다.
그렇다면 각 HTTP Method의 멱등성에 대해 좀 더 자세히 살펴보자

GET (O)

GET은 위의 표에서 멱등성을 만족하는 Method라는 것을 알 수 있다.
데이터 조회 한 번이든 여러 번이든 데이터의 수정이 일어나는 것이 아니기에 동일한 데이터가 조회되므로 멱등하다고 할 수 있다.
그렇지만 여러 번의 GET 요청 사이에 해당 데이터를 수정하는 PUT/PATCH나 데이터를 삭제하는 DELETE가 수행되었을 경우, 동일한 결과가 조회되지 않는다.
그렇다면 위의 내용을 토대로 멱등하지 않다고 볼 수 있는 것일까?
결론은 '아니다'. 멱등성은 외부 요인에 의해 데이터가 변경된 것은 고려하지 않고 서버 상태를 기준으로 판단하기 때문에 멱등하다고 볼 수 있다.
즉, GET에 의해 서버 상태가 바뀐게 아니라 PUT/PATCH/DELETE 등에 의해 서버 상태가 바뀐 것이기 때문이다.

DELETE (O)

DELETE를 한 번만 요청 시, 서버에서 해당 데이터가 삭제된다. 이 후 해당 데이터에 여러 번 DELETE 요청을 하더라도 이미 해당 데이터 삭제는 일어났기 때문에 서버의 상태는 더 이상 변하지 않기에 멱등하다고 볼 수 있다.
그렇지만 DELETE를 이용하여 멱등적이지 않은 설계를 할 수 도 있다.
예를 들어 가장 최근에 작성된 댓글을 삭제하도록 구현된 DELETE가 있다면, 다수의 DELETE 요청에 의해 매번 댓글이 삭제되게 된다.
이런 구현은 멱등성을 해치게 되기에, DELETE가 아닌 다른 방식으로 구현하는 것이 옳은 방법이라 할 수 있다.

POST (X)

POST는 요청을 보낼 때 마다, 신규 데이터가 생성되므로 멱등적이라고 볼 수 없다.

PUT (O)

PUT은 데이터를 변경하거나, 변경할 데이터가 없다면 신규 생성하게된다. 따라서, 한 번의 PUT 요청은 데이터를 신규 생성하거나 데이터를 변경하지만 여러 번의 PUT 요청은 이미 변경되었거나 생성된 데이터에 동일한 데이터를 덮어씌우는 요청이 되고 서버 상태는 동일하기에 멱등하다고 할 수 있다.

PATCH (X)

PUT과 PATCH의 차이점은 PUT이 전체 데이터 변경이라면 PATCH는 일부 데이터 변경이라는 점이다.
또한, PATCH는 요청을 구현하는 방법에 대한 제약이 없다.
PATCH가 위의 표에서 보면 멱등하지 않은 Method로 나와있지만 PUT과 같은 방식으로 사용한다면 멱등하게 설계도 가능하다.
그렇다면 PATCH의 멱등한 설계와 멱등하지 않은 설계에 대한 예시를 살펴보자

  • 멱등한 설계
    아래와 같이 수정할 부분만 정적으로 담아 요청한다면 멱등성을 보장받을 수 있다.
    즉, 여러 번의 요청을 받아도 동일한 결과를 가진다.
// 기존 데이터
{
	id: 15,
    name: "jiho",
    age: 25
}
// PATCH /user/15
{
	age: 20
}
// 변경된 데이터
{
	id: 15,
    name: "jiho",
    age: 20
}
  • 멱등하지 않은 설계
    위에서 말했듯이 PATCH 요청 구현은 방법에 제약이 없다
    따라서 아래와 같이 동적으로 나이를 증가시키는 변경을 구현할 수 있다.
    즉, 여러 번의 요청을 받으면 요청을 받을때마다 결과가 달라진다.
// 기존 데이터
{
	id: 15,
    name: "jiho",
    age: 25
}
// PATCH /user/15
{
    $increase: 'age',
    value: 1
}
// 변경된 데이터
{
  	id: 15,
    name: "jiho",
    age: 26         // 27, 28... 요청을 받을때마다 1씩 증가
}

참고문헌
토찌님의 HTTP 메서드
멋쟁이코더님의 HTTP요청과 멱등성 이해하기
Inpa님의 HTTP의 멱등성, 안전성, 캐시성 완벽 이해하기

profile
아마도 난 백엔드 style?
post-custom-banner

0개의 댓글