[rest] REST 거래?

REST에서 다음 유스 케이스를 어떻게 구현하는지 궁금합니다. 개념적 모델을 손상시키지 않고 할 수 있습니까?

단일 트랜잭션 범위 내에서 여러 리소스를 읽거나 업데이트하십시오. 예를 들어 Bob의 은행 계좌에서 John의 계좌로 $ 100를 이체하십시오.

내가 알 수있는 한, 이것을 구현하는 유일한 방법은 부정 행위입니다. John 또는 Bob과 연관된 자원에 POST하고 단일 트랜잭션을 사용하여 전체 조작을 수행 할 수 있습니다. 내가 아는 한, 이것은 실제로 개별 리소스에서 작동하는 대신 POST를 통해 RPC 호출을 터널링하기 때문에 REST 아키텍처를 손상시킵니다.



답변

RESTful 쇼핑 바구니 시나리오를 고려하십시오. 쇼핑 바구니는 개념적으로 트랜잭션 래퍼입니다. 장바구니에 여러 항목을 추가 한 다음 주문을 처리하기 위해 해당 바구니를 제출하는 것과 같은 방식으로 Bob의 계정 항목을 트랜잭션 래퍼에 추가 한 다음 Bill의 계정 항목을 래퍼에 추가 할 수 있습니다. 모든 조각이 제자리에 있으면 모든 구성 요소 조각으로 트랜잭션 래퍼를 POST / PUT 할 수 있습니다.


답변

이 질문에 의해 답변되지 않은 몇 가지 중요한 사례가 있습니다. 검색어에 대해 Google에서 높은 순위를 가지고 있기 때문에 너무 나쁘다고 생각합니다. 🙂

특히, 적절하게 좋은 방법은 다음과 같습니다. POST가 두 번 (중간에 일부 캐시가 걸려 있기 때문에) 두 번 전송하면 안됩니다.

이를 위해 트랜잭션을 객체로 만듭니다. 여기에는 이미 알고있는 모든 데이터가 포함될 수 있으며 트랜잭션을 보류 상태로 만듭니다.

POST /transfer/txn
{"source":"john's account", "destination":"bob's account", "amount":10}

{"id":"/transfer/txn/12345", "state":"pending", "source":...}

이 트랜잭션이 있으면 다음과 같이 커밋 할 수 있습니다.

PUT /transfer/txn/12345
{"id":"/transfer/txn/12345", "state":"committed", ...}

{"id":"/transfer/txn/12345", "state":"committed", ...}

이 시점에서 다중 풋은 중요하지 않습니다. txn의 GET조차도 현재 상태를 반환합니다. 특히, 두 번째 PUT은 첫 번째 PUT이 이미 적절한 상태에 있음을 감지하여 반환합니다. 또는 이미 “committed”상태에있는 후 “rolledback”상태로 전환하려고하면 오류 및 실제 커밋 된 트랜잭션 백.

단일 데이터베이스 또는 통합 된 트랜잭션 모니터가있는 데이터베이스와 통신하는 한이 메커니즘은 실제로 제대로 작동합니다. 트랜잭션에 대한 시간 제한을 추가로 도입 할 수도 있습니다. 원하는 경우 Expires 헤더를 사용하여 표현할 수도 있습니다.


답변

REST 용어에서 자원은 CRUD (create / read / update / delete) 동사로 수행 할 수있는 명사입니다. “송금”동사가 없기 때문에 CRUD로 처리 할 수있는 “트랜잭션”리소스를 정의해야합니다. 다음은 HTTP + POX의 예입니다. 첫 번째 단계는 것입니다 CREATE (HTTP POST 방법) 새로운 거래를 :

POST /transaction

이것은 “1234”와 URL “/ transaction / 1234″에 따라 트랜잭션 ID를 반환합니다. 이 POST를 여러 번 실행하면 여러 ID로 동일한 트랜잭션이 생성되지 않고 “대기 중”상태가 발생하지 않습니다. 또한 POST가 항상 dem 등원 (REST 요구 사항) 일 수는 없으므로 일반적으로 POST의 데이터를 최소화하는 것이 좋습니다.

트랜잭션 ID 생성을 클라이언트에 맡길 수 있습니다. 이 경우, 트랜잭션 “1234”를 작성하기 위해 POST / transaction / 1234를 POST하고 서버가 이미 존재하면 오류를 리턴합니다. 오류 응답에서 서버는 현재 사용되지 않은 ID를 적절한 URL로 반환 할 수 있습니다. GET은 절대로 서버 상태를 변경해서는 안되며 새 ID를 작성 / 예약하면 서버 상태가 변경되므로 GET 메소드를 사용하여 서버에 새 ID를 쿼리하는 것은 좋지 않습니다.

다음 으로 모든 데이터로 트랜잭션을 UPDATE (PUT HTTP 메소드)하여 암시 적으로 커밋합니다.

PUT /transaction/1234
<transaction>
  <from>/account/john</from>
  <to>/account/bob</to>
  <amount>100</amount>
</transaction>

ID가 “1234”인 트랜잭션이 이전에 PUT 인 경우 서버는 오류 응답을 제공하고 그렇지 않으면 확인 응답 및 완료된 트랜잭션을 볼 수있는 URL을 제공합니다.

주의 : / account / john에서 “john”은 John의 고유 계정 번호 여야합니다.


답변

훌륭한 질문은 REST는 주로 데이터베이스와 유사한 예제로 설명되며 무언가가 저장, 업데이트, 검색, 삭제됩니다. 서버가 어떤 식 으로든 데이터를 처리해야하는이 예제와 같은 몇 가지 예가 있습니다. Roy Fielding은 그의 논문에 어떤 것도 포함하지 않았다고 생각합니다.

그러나 그는 다음 상태로 링크가 이동하는 상태 머신으로서의 “표현 상태 이전”에 대해 이야기합니다. 이러한 방식으로 문서 (표현)는 서버가 수행하지 않고 클라이언트 상태를 추적합니다. 이런 식으로 클라이언트 상태는 없으며 현재 연결되어있는 상태 만 나타냅니다.

나는 이것에 대해 생각하고 있었고, 서버가 당신을 위해 무언가를 처리하게하고, 업로드 할 때 서버가 자동으로 관련 리소스를 생성하고 링크를 제공한다는 것이 합리적입니다. 자동으로 만들 필요는 없습니다. 링크를 알려줄 수 있으며, 링크를 만들 때만 따라야하는 경우에만 게으른 생성입니다. 또한 새로운 관련 리소스 를 만드는 링크도 제공합니다 . 관련 리소스는 동일한 URI를 갖지만 더 길어집니다 (접미사 추가). 예를 들면 다음과 같습니다.

  1. 모든 정보 가 포함 된 거래 개념을 업로드 ( POST )합니다 . 이것은 RPC 호출과 비슷하지만 실제로 “제안 된 트랜잭션 리소스”를 생성하고 있습니다. 예 : URI : /transaction
    결함으로 인해 각각 다른 URI를 가진 여러 리소스가 생성됩니다.
  2. 서버의 응답은 생성 된 리소스의 URI를 나타냅니다. 여기에는 새로운 “커밋 된 트랜잭션 리소스” 의 관련 리소스를 만들기위한 링크 ( URI )가 포함됩니다 . 다른 관련 리소스는 제안 된 거래를 삭제하는 링크입니다. 상태 머신의 상태는 클라이언트가 따를 수 있습니다. 논리적으로 이들은 클라이언트가 제공 한 정보를 넘어 서버에서 생성 된 리소스의 일부입니다. 예를 들어 URI를 : /transaction/1234/proposed, /transaction/1234/committed
  3. 당신 POST 링크의 정보는 다음의 제품에 은 “커밋 된 트랜잭션 자원”을 만들 서버의 상태 (두 계정의 잔액) **을 변경, 해당 자원을 만듭니다. 기본적으로이 리소스는 한 번만 만들 수 있으며 업데이트 할 수 없습니다. 따라서 많은 트랜잭션을 커밋하는 결함이 발생할 수 없습니다.
  4. 이 두 가지 리소스를 가져와 상태를 확인할 수 있습니다. POST가 다른 자원을 변경할 수 있다고 가정하면, 제안은 이제 “committed”(또는 아마도 사용 가능하지 않은) 플래그로 표시됩니다.

이것은 웹 페이지의 작동 방식과 유사하며 최종 웹 페이지에 “이 작업을 수행 하시겠습니까?”라는 메시지가 표시됩니다. 최종 웹 페이지 자체는 거래 상태를 나타내며 다음 상태로 이동하는 링크가 포함되어 있습니다. 금융 거래뿐만 아니라; 또한 (예) 위키 백과에서 미리보기를하고 커밋하십시오. REST의 차이점은 상태 시퀀스의 각 단계에는 명시 적 이름 (URI)이 있다는 것입니다.

실제 거래 / 판매에서는 거래 단계 (제안서, 구매 주문서, 영수증 등)마다 다른 실제 문서가 종종 있습니다. 정착 등 주택 구입에 훨씬 더

OTOH 이것은 의미론을 가지고 노는 것 같습니다. “동사 (RPC 호출) 대신 명사 (URI)를 사용하기 때문에”동사를 명사로 변환하는 명목 화가 불편합니다. 즉, 동사 “이 트랜잭션을 커밋”대신 명사 “커밋 된 트랜잭션 리소스”입니다. 명 목화의 한 가지 장점은 다른 방법으로 (예 : 세션 상태 유지와 같이, “이”트랜잭션이 무엇인지 알 수 있음) 이름을 지정하지 않고 이름으로 리소스를 참조 할 수 있다는 것입니다.

그러나 중요한 질문은이 접근법의 장점은 무엇입니까? 즉,이 REST 스타일은 RPC 스타일보다 어떤면에서 더 좋습니까? 웹 페이지에 유용한 기술이 저장 / 검색 / 업데이트 / 삭제를 넘어 정보 처리에도 도움이됩니까? REST의 주요 이점은 확장 성이라고 생각합니다. 그것의 한 측면은 클라이언트 상태를 명시 적으로 유지할 필요가 없습니다 (그러나 리소스의 URI에 암시 적으로 만들고 다음 상태는 그 표현의 링크로 암시합니다). 그런 의미에서 도움이됩니다. 아마도 이것이 레이어링 / 파이프 라이닝에도 도움이됩니까? OTOH는 한 명의 사용자 만 특정 거래를 볼 수 있으므로 캐싱하는 데 이점이 없으므로 다른 사용자가 읽을 수 있으므로 http의 큰 승리입니다.


답변

여기서 논의 내용을 요약 해보면 REST가 많은 API에 적합하지 않다는 것이 분명합니다. 특히 클라이언트와 서버의 상호 작용이 본질적으로 비 완전한 트랜잭션과 마찬가지로 상태 저장 상태 인 경우에는 더욱 그렇습니다. 문제에 맞지 않는 몇 가지 원칙을 따르기 위해 클라이언트와 서버 모두에게 제안 된 모든 후프를 뛰어 넘는 이유는 무엇입니까? 더 나은 원칙은 클라이언트에게 응용 프로그램을 작성하는 가장 쉽고 가장 자연스럽고 생산적인 방법을 제공하는 것입니다.

요약하면, 실제로 애플리케이션에서 많은 트랜잭션 (인스턴스가 아닌 유형)을 수행하는 경우 RESTful API를 작성하지 않아야합니다.


답변

나는 10 년 동안이 주제에서 멀어졌다. 돌아와서, 나는 당신이 구글 휴식 + 신뢰할 때 과학으로 위장하는 종교를 믿을 수 없습니다. 혼란은 신화입니다.

이 광범위한 질문을 세 가지로 나눌 것입니다.

  • 다운 스트림 서비스. 귀하가 개발하는 모든 웹 서비스에는 귀하가 사용하는 다운 스트림 서비스가 있으며 해당 트랜잭션 구문을 선택해야합니다. 이 모든 것을 서비스 사용자로부터 숨기고 작업의 모든 부분이 그룹으로 성공 또는 실패했는지 확인한 다음이 결과를 사용자에게 반환해야합니다.
  • 당신의 서비스. 고객은 웹 서비스 호출에 대한 명확한 결과를 원하며 실질적인 자원에 대해 POST, PUT 또는 DELETE 요청을 직접 수행하는 일반적인 REST 패턴은 이러한 확실성을 제공하는 가난하고 쉽게 개선되는 방법으로 저를 공격합니다. 안정성에 관심이있는 경우 작업 요청을 식별해야합니다. 이 ID는 클라이언트에서 생성 된 guid이거나 서버의 관계형 DB에서 시드 값일 수 있습니다. 서버 생성 ID의 경우 ‘사전 비행’요청-응답을 사용하여 조치의 ID를 교환하십시오. 이 요청이 실패하거나 절반 만 성공해도 아무런 문제가 없으면 클라이언트는 요청을 반복합니다. 사용하지 않은 ID는 해를 끼치 지 않습니다.

    이것은 모든 후속 요청이 완전히 dem 등원이되도록하기 때문에 중요합니다. n 번 반복 될 경우 동일한 결과를 리턴하고 더 이상 아무것도 발생하지 않는다는 의미입니다. 서버는 조치 ID에 대한 모든 응답을 저장하고 동일한 요청이 표시되면 동일한 응답을 재생합니다. 이 Google 문서 에는 패턴의 완전한 처리가 있습니다. 이 문서는 REST 원칙을 널리 따르는 구현을 제안합니다 (!). 전문가들은 반드시 그것이 다른 사람들을 어떻게 위반하는지 알려줄 것입니다. 이 패턴은 다운 스트림 트랜잭션과 관계없이 웹 서비스에 대한 안전하지 않은 호출에 유용하게 사용할 수 있습니다.

  • 업스트림 서비스로 제어되는 “트랜잭션”에 서비스 통합 웹 서비스의 맥락에서, 전체 ACID 트랜잭션은 노력 일반적으로 가치가없는 것으로 간주되지만 제공하여 서비스의 크게 도움 소비자는 취소 및 / 또는 확인 응답에서 확인 링크, 따라서 달성 할 수있는 보상에 의해 거래를 .

귀하의 요구 사항은 기본입니다. 사람들이 귀하의 솔루션이 정결하지 않다고 말하지 못하게하십시오. 문제를 얼마나 잘, 그리고 얼마나 간단하게 해결하는지에 따라 아키텍처를 판단하십시오.


답변

“트랜잭션 ID”유형의 tx 관리를 롤링해야합니다. 따라서 4 번의 호출이됩니다.

http://service/transaction (some sort of tx request)
http://service/bankaccount/bob (give tx id)
http://service/bankaccount/john (give tx id)
http://service/transaction (request to commit)

DB (로드 밸런싱 된 경우) 또는 메모리 등에 작업 저장을 처리 한 다음 커밋, 롤백, 시간 초과를 처리해야합니다.

실제로 공원에서 편안한 하루가 아닙니다.