멱등성(idempotence)

세정·2024년 1월 10일

동일한 작업을 반복 수행하더라도 항상 동일한 결과를 보장하는 성질.

여러 번 동일한 요청을 보내더라도, 최종 결과는 초기 요청과 동일하게 된다.

수학에서의 멱등성은 어떤 연산을 여러 번 수행하더라도 그 결과가 변하지 않는 것을 의미한다.

f(f(x)) = f(x) 일 때, f(x)는 멱등하다.

컴퓨터 과학에서는 이 개념을 API 호출, 데이터베이스 작업 등 다양한 상황에 적용할 수 있다!
이는 동일한 요청을 여러 번 보내더라도 시스템의 상태를 변경하지 않으면서 안정적으로 작업을 수행할 수 있도록 도와주며, 결과 예측 가능성을 높일 수 있다.



멱등성의 기준

주로 해당 요청이 서버 상태나 데이터에 어떠한 변경을 가하고 있는지에 따라 결정된다. 여러 요청을 보냈을 때 같은 리소스나 상태에 대해 항상 동일한 결과를 얻는 경우 해당 요청은 멱등성이 있다고 볼 수 있다.

멱등성의 판별 기준은 주어진 요청이 서버나 시스템의 상태를 어떻게 변경시키는지를 고려하는 것이 중요하다. 동일한 요청을 보냈을 때 항상 동일한 결과를 가져야 하고, 이로 인해 서버나 데이터의 상태가 변하지 않을 때 멱등성을 가진다.



HTTP 메서드와 멱등성의 관계

GET

GET 메서드는 멱등성을 가지는 안전한 메서드이다. 안전한 메서드는 해당 요청이 서버에 부작용을 일으키지 않음을 의미한다. GET 메서드는 보낸 횟수와 관련 없이 항상 동일한 응답값을 반환한다. 단순 데이터를 읽어들이는 요청으로, 서버의 상태에 영향을 주지 않아 멱등하다고 할 수 있다.

상품 목록 조회 예시를 들어보겠다.

GET 요청: GET /items

응답 값:

[
  {"id": 1, "name": "mouse", "price": 8.0},
  {"id": 2, "name": "keyboard", "price": 23.0},
  {"id": 3, "name": "headphone", "price": 36.0}
]

첫 번째 요청과 두 번쨰 요청 사이에 어떤 작업이 발생하더라도 GET 요청에 대한 응답은 항상 동일한 물건 목록을 반환한다. 동일한 요청을 여러 번 보내도 항상 동일한 결과값을 보장한다!


POST

POST 메서드는 멱등성을 가지고 있지 않다. 이는 서버의 상태를 변경하거나 새로운 리소스를 생성할 때 사용되는데, 같은 요청을 여러 번 보내면 각각의 요청마다 서버의 상태가 변경될 수 있다.

새로운 상품 추가 예시를 들어보겠다.

POST 요청: POST /items

{
    "name": "moniter",
    "price": 25.0
}

응답 값:

{
    "id": 4,
    "name": "moniter",
    "price": 25.0
}

PUT

PUT 메서드 클라이언트가 제공한 데이터로 리소스를 완전히 대체하는 메서드이다. 동일한 요청을 반복해서 보내더라도 항상 같은 상태로 리소스가 업데이트되거나 생성된다는 점에서 멱등성을 가진다.

상품 정보 변경 예시를 들어보겠다.

기존 상품 정보

{
  "id": 1,
  "name": "mouse",
  "price": 8.0,
  "description": "vertical mouse"
}

PUT 요청: PUT /items/1

{
  "id": 1,
  "name": "vertical mouse",
  "price": 12.0
}

응답 값:

{
  "id": 1,
  "name": "vertical mouse",
  "price": 12.0,
  "description": null
}

응답 값을 보면, 특정 제품의 이름과 가격은 정상적으로 업데이트 되었고 설명은 null 값으로 대체되었다. 이 요청은 리소스를 완전히 대체하는데, 동일한 요청을 여러 번 보내더라도 리소스는 항상 동일한 상태로 업데이트된다.
즉, 같은 요청이면 항상 동일한 결과를 얻게 됨을 알 수 있다.

** PUT 메서드는 원칙적으로 일부 값만 요청한 경우에 지정하지 않은 리소스들은 null 혹은 default 값으로 대체되는데, 서버 동작 방식이나 특별한 매커니즘에 따라 기존 값을 유지할 수 있다고 한다.
그래도 일부 값 변경 시에는 PATCH, 전체 값 변경 시에는 PUT을 사용하는 게 일반적이다!


PATCH

PATCH 메서드는 일반적으로 리소스의 일부만 업데이트할 때 사용된다. 클라이언트가 보내는 데이터에 포함된 필드만 해당 리소스에서 변경하고, 나머지는 변경되지 않은 채로 유지된다. 이러한 유연성은 필드 일부분을 변경할 때 유용하다.

PATCH 메서드는 설계에 따라 멱등성을 가질 수도 있고 가지지 않을 수도 있다.
일부 업데이트 작업이 리소스의 상태를 변경하지 않는다면 일부 멱등성의 특징을 띌 수는 있다. 하지만 실제로는 리소스의 일부를 수정하는 것이므로, 멱등성이 달라질 수 있다.
일반적으로 PATCH 메서드는 리소스의 부분적인 수정을 목적으로 하기 때문에 설계에 따라 멱등하지 않다고 간주된다. 일부 구현이나 상황에 따라 멱등성을 유지할 수는 있지만, 일반적인 RESTful API 디자인에서는 멱등하지 않다고 가정하는 것이 표준적 관례이다.

상품 정보 변경 예시를 들어보겠다.

기존 상품 정보

{
  "id": 1,
  "name": "mouse",
  "price": 8.0,
  "description": "vertical mouse"
}

PATCH 요청: PATCH /items/1

{
  "price": 12.0
}

응답 값:

{
    "id": 1,
    "name": "mouse",
    "price": 12.0,
    "description": "vertical mouse"
}

응답 값을 보면 제품 가격만 변경 되었고 나머지는 기존 값 그대로 유지되고 있는 걸 알 수 있다. 이렇게 PATCH 메서드를 사용하면 전체 리소스를 대체하는 PUT과는 달리, 클라이언트가 제공한 필드 값만을 업데이트하여 리소스를 부분적으로 수정한다.

PATCH 메서드의 경우 일부 필드만을 대상으로 하며, 이것이 멱등성을 보장하는 것은 아니다.

관련하여 추가적인 예시를 들어보겠다.

기존 상품 정보

{
    "id": 1,
    "name": "mouse",
    "price": 8.0,
    "description": "vertical mouse"
}

이 상태에서 price를 +10.0 하도록 한 번 요청을 보내면 결과로는 18.0이 나올 것이다. 하지만 계속적으로 요청을 보내면 보낸 만큼 결과가 10.0씩 늘어나, 멱등성을 보장하기 어렵다.

이렇게 특정 요청이 리소스의 일부를 수정하더라도 다른 부수적인 영향을 주는 경우에는 멱등성을 보장하기 어렵다.
따라서 일부 멱등성의 특성을 보일 수 있지만, 요청의 성격에 따라서 멱등성을 보장하지 못할 수도 있다.
(PUT과 PATCH: https://www.inflearn.com/questions/110644/patch-%EB%A9%94%EC%84%9C%EB%93%9C%EA%B0%80-%EB%A9%B1%EB%93%B1%EC%9D%B4-%EC%95%84%EB%8B%8C-%EC%9D%B4%EC%9C%A0)


DELETE

DELETE 메서드는 특정 리소스를 삭제할 때 사용되며, 삭제된 리소스에 대한 추가적인 요청은 항상 동일한 결과를 반환한다. 리소스를 삭제하고 나면 해당 리소스가 존재하지 않는 상태가 되기 때문에, 동일한 요청이 여러 번 보내져도 동일한 결과를 반환하므로 멱등성을 가진다.

특정 제품 삭제 예시를 들어보겠다.

DELETE 요청: DELETE /items/1

위 요청은 서버에서 id가 1인 리소스를 삭제할 것을 요구한다. 서버는 해당 리소스를 삭제하고, 클라이언트에게 삭제 작업에 대한 응답을 반환한다. 일반적으로 200 OK와 함께 삭제된 리소스에 대한 정보가 없는 응답을 반환한다.

첫 번째 DELETE 요청이 성공하여 리소스가 삭제된 후, 다시 동일한 리소스를 삭제하는 DELETE 요청을 보내더라도 이미 삭제된 리소스에 대한 요청이기 때문에 클라이언트에게는 삭제된 리소스에 대한 정보가 없는 404 에러가 반환될 것이다.

멱등성은 동일한 요청에 대해 항상 동일한 결과를 보장하는 것이지만, 이것은 클라이언트가 보낸 요청과 관련된 결과여야 한다. 따라서 유효한 요청이었지만 이미 삭제된 리소스에 대한 요청이기 때문에 404 에러를 반환하게 되는 것이다.
같은 요청이라도 이미 수행된 동작에 따라 결과가 달라질 수 있지만, 그 요청 자체는 멱등성을 가지고 있다고 볼 수 있다.



멱등성과 오류 처리

멱등성과 오류 처리는 서로 밀접한 관련이 있다. 일반적으로 오류는 클라이언트와 서버 사이의 통신 문제, 데이터베이스의 일시적 문제, 또는 다른 네트워크 관련 문제 등 다양한 이유로 발생한다.

이를 처리할 때 멱등성은 유용하게 사용된다. 예를 들어, 클라이언트가 요청을 보냈지만 응답을 받지 못했거나, 오류 응답을 받은 경우 동일한 요청을 다시 시도할 수 있다. 이 때 멱등성이 보장된다면, 동일한 요청을 여러 번 시도해도 항상 동일한 결과를 받을 수 있으므로 오류 복구에 유용하다. 이러한 방식으로 멱등성은 시스템에서의 오류 처리 및 재시도 매커니즘을 지원한다.



멱등성의 한계(제약)

  1. 부수 효과(side effect)가 있는 작업
    : 부수 효과가 있는 작업(파일 생성/메일 전송)은 한 번 실행되면 이미 시스템 상태가 변하므로 멱등성을 가질 수 없다.

  2. 시스템 간 통신 문제
    : 외부 시스템과의 상호작용에서 요청이 중간에 끊기거나, 동일한 요청이라도 외부 상황에 따라 다른 결과를 얻을 수 있다.

  3. 동시성 충돌
    : 여러 클라이언트가 동시에 같은 리소스에 대한 변경 요청을 하게 되면 충돌이 발생할 수 있다.




잘못된 정보가 있다면 댓글로 알려주세요!!

profile
하이

0개의 댓글