부수적 인 영향을 미치는 PUT을 사용하고 있음 (REST)


9

사용자가 양식을 업데이트 할 때마다 실행 취소 기록을 만들고 싶습니다. 업데이트이기 때문에 PUT 요청을 사용하고 싶습니다. 그러나 PUT에는 부작용이 필요 없다는 것을 읽었습니다 .

여기서 PUT을 사용할 수 있습니까? 더 나은 대안이 있습니까?

PUT /person/F02E395A235

{
   time: 1234567,
   fields: {
      name: 'John',
      age: '41'
   }
}

서버에서

doPut('person/:personId',
   // create a new person snapshot
)

편집하다:

여러 번 호출하면 여러 버전이 생성됩니다.

해결책은 버전을 만들기 전에 버전이 고유한지 확인하는 것이 었습니다.

답변:


11

HTTP / 2를 작성하는 사람들은 오래된 의미를 유지하면서 HTTP의 기능에 대한 그들의 아이디어에 대해 훨씬 더 장황했다. dem 등식에 대한 HTTP / 2 초안 스펙이 무엇을 말하는지 보자.

4.2.2. dem 등식 방법

해당 방법으로 여러 동일한 요청이있는 서버에 의도 된 효과가 단일 요청에 대한 효과와 동일하면 요청 방법은 "등전위"로 간주됩니다. 메소드는 dem 등원입니다.

안전 정의와 마찬가지로 dem 등원 속성은 사용자가 요청한 내용에만 적용됩니다. 서버는 각 요청을 개별적으로 기록하거나, 개정 제어 히스토리를 유지하거나, 각 dem 등원 요청에 대해 다른 비등 전성 부작용을 구현할 수 있습니다.

이러한 각 PUT 요청 에 대해 서버에 의도 된 효과해당 URI로 식별 된 자원업데이트하는 것 입니다. 이것이 바로 귀하의 경우에 일어나는 일입니다.

리소스를 버전으로 결정한다는 것은 실제로 중요하지 않습니다. 아무것도 변경되지 않은 상태에서 새 버전을 만들지 않으려면 PUT 요청의 페이로드를 가장 최근의 (또는 다른 방법으로 식별 된) 버전의 리소스와 속성이 변경되지 않은 경우와 비교해야합니다. 새 버전을 만들지 않도록 선택할 수 있습니다 .


편집 :

기록은 사용자에게 표시되며 여러 번 호출하면 다중 버전이 생성됩니다.

자원에 관한 한, 부작용 은 없습니다 . 해당 URI의 리소스는 변경되지 않습니다 (동일한 속성은 PUT을 얻습니다). 히스토리는 메타 데이터 일 뿐이며 다른 URI 또는 ​​다른 요청 헤더로 요청 될 가능성이 높습니다.


"PUT이 사용자가 볼 수있는 기록을 만들 수 있습니까?"라는 특정 문제에 대한 답변을 제외하고는 해결책을 주셔서 감사합니다.
roo2

그게 무슨 문제입니까? 그건 time속성이 업데이트 될 때? 리소스 있지만 메타 데이터도 마찬가지라고 생각 합니다.
CodeCaster

1
문제는 여러 개의 PUT이 전송되면 사용자는 중복 정보로 오랫동안 실행 취소 기록을 얻게된다는 것입니다. 독창성을 확인하면 해결됩니다
roo2

12

HTTP는 두 가지 속성을 구분합니다.

  • dem 등
  • 안전

Idempotency는 스펙에 의해 다음과 같이 정의됩니다.

또한 메소드는 " 오류나 만기 문제를 제외하고" N> 0 개의 동일한 요청의 부작용이 단일 요청의 부작용과 동일하다는 점에서 " 등식 성 " 의 속성을 가질 수 있습니다 . 방법은 , , 및 이 속성을 공유 할 수 있습니다. 또한, 상기 방법 및 SHOULD NOT들은 부작용을 가지고, 따라서 본질적 멱등된다.GETHEADPUTDELETEOPTIONSTRACE

그리고 안전 :

특히, 대회는 것을 설립되었습니다 GETHEAD방법은 해서는 안 검색 이외의 작업을 수행하는 의미를 가지고있다. 이 방법들은 " 안전한 " 것으로 간주되어야합니다 . 이것은 사용자 에이전트와 같은 다른 방법을 나타낼 수 있습니다 POST, PUT그리고 DELETE사용자가 안전하지 못한 처리를 요구하고 있다는 사실을 알게되고 그래서, 특별한 방법으로.

당연히, GET요청 을 수행 한 결과로 서버가 부작용을 일으키지 않도록 보장 할 수는 없습니다 . 실제로 일부 동적 자원은 해당 기능을 고려합니다. 여기서 중요한 차이점은 사용자가 부작용을 요청하지 않았으므로 책임을 질 수 없다는 것입니다.

안전성은 dem 등원을 의미한다는 점에 유의하십시오. 방법에 부작용이 없다면 여러 번 수행하면 한 번만 수행하는 것과 같은 부작용이 발생하지 않습니다.

이 방법은 세 가지 범주로 분류됩니다.

  • 안전 (따라서도 및 나무 등) : GET, HEAD, OPTION,TRACE
  • dem 등이지만 반드시 안전 할 필요는 없습니다 : PUT,DELETE
  • dem 등하거나 안전하지 않습니다. POST

PUT에는 부작용이 없어야합니다.

그건 잘못이야 PUTdem 등이지만 안전하지는 않습니다. 요점 의은 PUT즉 자원을 업데이트하는 부작용을 가지고있다. dem 등원의 의미는 동일한 내용으로 동일한 자원을 여러 번 업데이트하면 한 번만 업데이트하는 것과 동일한 효과를 가져야한다는 것입니다.

안전 [강조 광산]에 관한 섹션의 마지막 단락에 유의하십시오.

당연히, GET요청 을 수행 한 결과로 서버가 부작용을 일으키지 않도록 보장 할 수는 없습니다 . 실제로 일부 동적 자원은 해당 기능을 고려합니다. 여기서 중요한 차이점은 사용자가 부작용을 요청하지 않았으므로 책임을 질 수 없다는 것 입니다.

이 문장은 GET안전 에 대해 이야기하지만 저자는 동일한 추론 PUT과 dem 등식 을 적용한다고 가정 할 수 있습니다 . IOW : PUT하나의 사용자가 볼 수있는 부작용, 즉 명명 된 리소스를 업데이트해야합니다. 다른 부작용 이 있을 수 있지만 사용자는 이에 대해 책임을지지 않습니다.

예를 들어, PUTdem 등원이라는 사실 은 내가 원하는만큼 자주 다시 시도 할 수 있음을 의미합니다. 스펙 여러 번 실행하면 한 번 실행하는 것과 정확히 동일하다는 것을 보장 합니다. 이러한 여러 PUT요청 의 부작용으로 이전 개정의 백 로그를 작성하는 것이 완벽하게 유효 합니다. 그러나 여러 번의 재시도 결과로 데이터베이스가 이전 개정판의 백 로그로 가득 차게되면 문제가되지 않습니다.

IOW : 원하는만큼 부작용을 가질 수 있지만

  1. 요청이 dem 등인 것처럼 사용자에게 보여야합니다.
  2. 사용자가 아닌 부작용에 대한 책임

그러나 dem 등원 (Idempotency)은 PUT 행위에 의해 영향을받는 다른 서버 / 서비스 상태가 아니라 배치되는 리소스 상태에 관한 것입니다.
Marjan Venema 2014

휴식의 안전과
dem

좋은 설명입니다. 그러나 "PUT의 요점은 부작용 즉, 리소스를 업데이트하는 것입니다."와 같은 몇 가지 진술을합니다. "부작용"이라는 용어가 "일차적 인 의도 된 효과에 추가로 발생하는 이차적이거나 의도하지 않은 것"과 다른 용어를 의미하지 않는 한 모순처럼 보입니다.
MarredCheese

@MarredCheese : 표준 프로그래밍 의미에서이 용어를 사용하고 있는데, 이는 기본적으로 "반환 값이 아닌 '결과'"를 의미합니다.
Jörg W Mittag

아 물론 이죠 설명해 주셔서 감사합니다.
MarredCheese

1

PUT에 부작용이 없어야 한다는 것은 맞지만 , 이것에 뭔가를 추가 할 것입니다.

PUT은 해당 PUT 조작이 수행되는 자원에 부작용이 없어야합니다.

person로 식별 되는 리소스를 업데이트하고 F02E395A235있으므로 PUT을 사용하는 것이 정확합니다. 이제 비즈니스 규칙으로 호출 엔티티 (REST 서비스의 소비자)에게는 보이지 않는 변경 사항도 추적합니다. person리소스에 새 항목이 추가되지 않습니다 . /person/엔드 포인트를 사용하여 히스토리 스냅 샷에 액세스 할 수 없습니다 . 따라서이 경우 PUT이 완벽하게 수용 가능해야한다고 생각합니다.


1
자원에 대한 부작용은 없지만 다른 항목 (카운터, 로깅, 감사 추적 등)에 대한 부작용은 완벽하게 허용됩니다.
Marjan Venema 2014
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.