멱등성과 HTTP에 대한 생각

[주의] 틀리다 맞다의 이야기를 하려고 쓰는 글은 아닙니다.

수학 혹은 컴퓨터분야에서 쓰이는 용어라고 한다. 한문과 한글이 평생 부족한 나로서는 뭔말인가 싶어서 열심히 구글링을 해봤다. “연산을 여러번 하더라도 결과가 달라지지 않는 성질” 이라는 정의라고 한다. 대부분의 포스트에서 HTTP Method를 예를 들어 설명하는데 이해가 안가는 부분이 있었다. HTTP GET, PUT, DELETE 등은 멱등성을 유지하는 반면 POST는 유지하지 못한다라는 구절이었는데, 자세히 그 내막(?)을 살펴보고자 한다.

결과가 달라지지 않는다고?

예를 들어 상품을 조회하는 HTTP API가 있다고 가정하자

1
2
3
4
5
6
7
HTTP GET /products
200 OK
{
"productName": "상품명",
"price": 25000,
....
}

위의 JSON 결과에서 상품명과 가격은 외부 요인에 의하여 얼마든지 바뀔 수 있는 결과이다. 그렇다면 한번 호출한 결과와 여러 번 호출한 결과가 다를 수도 있다는 이야기로 해석이 되는데, 결과적 일관성은 유지하지 못하는거 아닌가?라는 생각이 들었다. 그렇다면 조금 다른 예로 생각을 해보려고 한다.

특정 사용자를 조회하는 HTTP API가 있다고 가정해보자.

1
2
3
4
5
6
7
8
GET /users/1 HTTP/1.1
200 OK

{
"userName": "Ryan",
"tel": 010-0000-1111,
....
}

사용자 키(1)를 기준으로 사용자의 프로필 비슷한 내용을 조회하는 API이다. 만약, 리소스에 대한 접근(변경,삭제)을 해당 키에 대한 리소스 오너만 할 수 있는 상황이라면 위에서 설명한 멱등성이 보장될 수 있다고 판단된다.
그렇다면 멱등성이라는 성질을 HTTP API를 통하여 접근하는 리소스에 비춰 생각해봤을 때, 리소스에 접근할 수 있는 범위 혹은 스코프가 어떻게 되느냐에 따라서 결과적 멱등성 여부가 달라지지 않을지지 않을까 라는 조심스러운 생각이 들었다.

그렇다면 인터넷에 돌아다니는 여러 글과 포스트들은 잘못된 이야기를 하고 있는 것일까?

아마 멱등성이라는 의미가 협의보다는 광의로서 구조 또는 효과 측면에서의 동일함을 가리키지 않나라는 생각이 들었다. 앞서 설명한 두 개의 API는 특별한 제약 조건이 없는 상황이라면 동일한 응답 스트럭쳐와 동일한 HTTP Response를 가지게 될 것이고, 서버에서도 동일한 상태를 유지하게 될 것이다. 결과적으로 세세한 응답 하나하나의 결과적 멱등성을 가리키는 용어가 아닌 구조 혹은 효과의 측면에서 동일함을 유지해야 한다 라고 정리할 수 있을거 같다.

여기까지 순전히 GET에 대한 이야기만 했다. 그렇다면 리소스에 대한 추가/변경/삭제 오퍼레이션에 해당하는 POST, PUT, DELETE는 어떻게 이해하면 좋을까?

1
2
3
4
5
6
POST /users HTTP/1.1

{
"userName": "Ryan",
"tel": 010-0000-1111,
}

이번에는 사용자 리소스를 생성하는 API로 설명해보려고 한다. 해당 API는 처음 호출한 결과와 두 번째 호출한 결과가 명확하게 달라져야 정상이다.

첫 번째의 경우 응답은 201 Created 혹은 200 OK가 올 것이고 두 번째 호출 결과는 400 Bad Request(통신 자체는 성공했으니 2XX로 해석하는 것도 가능하다. 의견이 분분한 부분이다.) 혹은 200 OK의 응답은 오지만 첫 번째의 응답 결과와 결코 같을 수는 없을 것이다. 하지만, 세 번째 그리고 N번째 호출까지는 모든 응답이 두 번째 호출과 동일한 상황일 것이다. 이렇다면 위에서 말한 구조 혹은 효과 측면에서는 동일함을 유지하는 것이라고 생각할 수 있지 않을까?

만약, 사용자를 등록하는 API가 아니라 매번 리소스를 생성하는 API가 있다고 하더라도 구조와 효과적인 측면에서 매번 동일할테니 이거 역시 멱등성을 유지한다고 봐도 무관하지 않을까? 라는 생각이 들었다.

이 글을 혹시나 보는 사람은 뭐 이런 억지...라고 생각할지도 모르겠다. 하지만 HTTP RFC 명세를 살펴보면 아래와 같이 명시하고 있는 부분이 있다.
스크린샷 2020-03-05 오전 2.08.56

아마 스펙에서 말하는 멱등한 성격에 대해 정확한 이해가 부족하여 이런 일과 생각이 벌어지지 않았나 하는 생각이 든다. 하지만 스펙은 스펙일뿐 꼭 지켜야 하는 건 아니라고 생각한다.

차라리 멱등성을 설명하는 좋은 예는 아마 함수형 프로그래밍에서 말하는 순수 함수 혹은 참조 투명성과 같은 개념이 더 어울리지 않나…하는 생각이 든다.

참고 리소스