REST를 통한 트랜잭션을 달성 할 수없는 경우 REST가 어떻게 정말로 유용 할 수 있습니까?
REST를 살펴볼 때 가장 먼저 눈에 띄는 것 중 하나는 트랜잭션 의미 체계가 정의되어 있지 않다는 것입니다. 일부는 이것이 REST가 무엇인지에 대해 암시 적으로 반대한다고 말하는 반면 다른 사람들은 그렇게하려는 시도가 REST 시스템을 '오염'시킬 것이라고 말합니다. .
그러나 REST가 대중적인 'api'선택이되었고 우주의 모든 사이트가 편안한 진입 점을 노출하기 시작했다고 주장 할 수 있습니다.
트랜잭션 동작없이 정확히 어떻게 사용할 수 있습니까 (그리고 저는 보상하지 않는 것입니다)? REST의 이점 중 하나는 데이터 구성 요소를 분해한다는 것이므로 스마트 클라이언트가 여러 서비스에서 데이터를 구성하고 이러한 구성된 데이터를 추가 및 조정하도록 할 수 있다고 생각할 것입니다. 그러나 이러한 데이터 구성을 원자 적으로 분리하여 변경할 수 없으면 REST를 사용할 수 없게됩니다.
시간이 지남에 따라 진지한 데이터 노출의 필요성이 도래함에 따라 우리는 단순하고 (REST가 승리)이 데이터를 안정적으로 조작 할 수 있도록 트랜잭션 동작을 지원하는 것을 원할 것입니다.
자, 저는 제 연구에서 특정 논증을 몇 번 읽었으며, REST에서 트랜잭션에 대해 어떻게 생각해야하는지와 관련이 있습니다. 주어진 예는 장바구니입니다. 당신입니다.
그러나 나는이 주장에 동의하지 않는다. 첫째, 쇼핑 카트에있는 격리는 단지 편리하다. 이것은 트랜잭션 격리가 아니다. 내 애플리케이션의 일부가 데이터를 읽는 동안 카트에 대해 동시에 작업을 수행하면 어떻게 될까? 그것에서? 내 응용 프로그램의 읽기 부분이 '아직 트랜잭션중인'데이터를 볼 것이라고 기대하지 않습니다.
모든 데이터 변경에 암시 적 트랜잭션 모델이있는 것은 아니지만 여러 서비스에 대한 트랜잭션은 확실히 그렇지 않습니다.
트랜잭션이 발생해야하며 실제 REST 호출이 사실을 무시할 수있는 방식으로 발생해야하는 것 같습니다 (나머지 페이로드에 추가하는 것은 크지 않지만 헤더를 추가하는 것은 괜찮음).
REST를 통해 트랜잭션 모델을 만들 수있는 방법에 대한 몇 가지 제안을 읽었으며 작성중인 일부 사양은 매우 최근 인 것 같습니다.
이것에 대한 진짜 생각이 있습니까? REST의 단순한 특성이 견고한 데이터 조작 ( '산'트랜잭션)에 대해 활용 될 수 있도록 REST보다 '더 많은'것이 있으면 안됩니다.
만약 그렇지 않다면 우리가 정말로 비용을 높이고 서비스 개발자에게 순수한 데이터 세계에서 상호 작용하려면 비누와 같은 모 놀리 식을 지원해야한다고 말할까요? 또는 더 나쁜 것은 자체 사용자 정의 트랜잭션 지원을 REST와 같은 것으로 구축하여 각 서비스를 비표준으로 만들고 REST의 전체 기능을 깨뜨리는 것입니까?
어떤 생각이라도 미리 감사드립니다.
편집, 간단한 시나리오 추가 :
사용자에게 아티스트 리소스에 대한 URI를 제공하도록 요청하는 대신 사용자에게 아티스트 리소스에 대한 URI를 요청하는 대신 앨범 생성을 처리하는 앨범 생성을 처리하는 클라이언트 양식을 상상해보십시오 (아티스트 카탈로그에서 가져올 가능성이 가장 높음). .
사용성을 위해 클라이언트는 아티스트 이름을 수동으로 작성하여 아티스트 '인라인'을 만들 수 있습니다. 게시 시나리오에서 클라이언트 코드는이를 이해하고 앨범 생성 요청을 보내기 전에 먼저 결정을 시도합니다. 아티스트가 이미 존재하는 경우 해당 아티스트에 대한 uri를 가져오고, 그렇지 않으면 아티스트를 생성하고 아티스트 uri를 가져옵니다.
그런 다음 클라이언트 코드는 계속해서 앨범을 생성합니다. 이것은 일반적인 클라이언트보다 더 똑똑하며 REST 및 '멍청한'게시 바로 위에 위치하지 않고 대신 순수한 REST 로직을 처리하는 일부 상호 작용이 있습니다.
그러나이 시나리오에서는 아티스트가 먼저 생성되므로 앨범이 생성되지 않는 한 아티스트가 생성되지 않도록하는 것이 좋습니다.
이것은 트랜잭션이 의미하는 것처럼 '중요한'것은 아니지만 클라이언트 코드가 하나의 작업으로 발생하는 것을 선호하는 일련의 작업을 정의합니다 (결국 사용자에게 단일 작업처럼 보이게 함).
이 시나리오에 대해 내가 본 유일한 지침은 앨범 생성이 실패 할 경우 클라이언트가 보상 조치를 취하고 특히 아티스트를 삭제하도록 요청하는 것입니다. 그러나 이것은 문제가되는 것 같습니다. 클라이언트가 아티스트가 고립되어 있다고 가정하고 있기 때문에 다른 클라이언트가 이미 그 아티스트를 '보고'할당하면 어떻게됩니까?
이것은 데이터 변경에 대한 나의 우려이며, 확실히 다른 갭 (아티스트는 나중에 삭제 될 수 없다고 말하는 사람)이 있지만, 이러한 작업은 투명하지 않습니다 (즉, 작업이 자동화 된 것이 아닙니다. 클라이언트이지만 사용자가 특별히 요청한 것).
나는 그것이 주제를 밝히는 데 도움이되기를 바랍니다.
트랜잭션에 대해 이야기 할 때 분산 된 2 단계 커밋 프로토콜에 대해 이야기한다고 가정하겠습니다 .
내가 올바르게 이해한다면 REST가 개별 REST 요청에서 트랜잭션을 지원할 수없는 경우 REST를 사용하여 여러 시스템에 걸친 작업을 수행하는 방법을 이해하려고합니다. 문제는 일관성을 달성하기 위해 트랜잭션을 사용해야한다는 잠재적 인 결함이있는 가정을하고 있다는 것입니다. 우리는 그것들을 사용하기 위해 어떤 대가를 지불하고 있으며 어떤 대안이 있습니까?
Amazon에서 일했으며 현재 Microsoft에 근무하는 Pat Helland는 Life beyond Distributed Transactions 라는 논문을 썼습니다 . 논문에서 저자는 다음과 같이 진술합니다.
안타깝게도 전자 상거래, 공급망 관리, 금융 및 건강 관리 애플리케이션과 같은 비즈니스 목표를 해결하기 위해 노력하는 프로그래머는 분산 트랜잭션없이 확장하는 것에 대해 점점 더 고민해야합니다. 분산 트랜잭션을 사용하려는 시도가 너무 취약하고 성능이 좋지 않기 때문에 이렇게합니다.
그의 논문은 확장 성과 성능이 우수한 분산 트랜잭션에 대한 대체 솔루션을 탐구합니다.
REST는 트랜잭션을 지원하지 않기 때문에 성공할 수 있습니다. REST라는 용어를 발명 한 Roy Fielding의 인용문입니다.
분산 트랜잭션 프로토콜이 필요한 경우 아키텍처가 REST 기반이라고 어떻게 말할 수 있습니까? 클라이언트와 하이퍼 미디어에서 RESTful 애플리케이션 상태를 사용하여 모든 상태 전환을 결정하는 한 상황에서 클라이언트가 서버에 관리 방법을 알려야하는 트랜잭션 의미의 분산 합의가 필요한 다음 상황으로 어떻게 이동할 수 있는지 알 수 없습니다. 자체 자원.
... 지금은 "나머지 거래"가 모순이라고 생각합니다.
이것은 2009 년 6 월 9 일에 REST 토론 목록에있는 메시지에서 가져온 것입니다. Yahoo 그룹은 쓸모 없기 때문에 링크를 제공 할 수 없습니다.
ReST 애플리케이션에서 트랜잭션을 원하는 경우 ReST API 기능에서 일반적으로 기술자 웹 서비스 담당자가 Google을 사용하고 있기 때문입니다.
다른 방식으로 살펴 보겠습니다.
Soap googles on : 트랜잭션을 열고, 고객 레코드를 만들고, 주문 레코드를 만들고, 트랜잭션을 커밋합니다.
ReST Googles on : 서버에 무엇을해야하는지 물어보십시오. 서버는 "고객 리소스 생성"이라고 말하므로 POST / customers입니다. 서버는 "원하는 경우 이제 주문을 생성합니다"라고 말하면 클라이언트는 양식에 따라 주문을 생성합니다.
ReST에서 애플리케이션 프로토콜 은 트랜잭션 경계가있는 데이터가 아니라 생성되고 조작되는 리소스로 표현됩니다.
이러한 모든 작업을 포괄하는 장기 실행 트랜잭션을 원한다면 클라이언트가 아닌 서버 가이를 시작하기로 결정합니다.
서버 측에서 장기 실행 트랜잭션을 계속 구현할 수 있습니다. 클라이언트 측에서 트랜잭션을 원하면 클라이언트가 실행하지 않을 모든 작업과 해당 작업 사이에 존재하는 트랜잭션 경계를 이미 알고 있다고 가정합니다. 이것이 클라이언트에 대한 기대치라면 나머지 아키텍처의 늦은 바인딩, 하이퍼 미디어 기반 특성을 이미 포기한 것입니다.
따라서 실제로 ReST를 수행하지 않고 http를 통해 RPC에 맞추려고하면 트랜잭션이없는 문제가 발생합니다.
일반적으로 트랜잭션이 필요한 대부분의 작업은 트랜잭션없이 발생하도록 재 작업 할 수 있다고 생각합니다.
예를 들어, 전형적인 은행 송금입니다. 계정 A에서 B로 $ 100를 이동한다고 가정합니다.
거래 시작 / 차변 A, $ 100 / 크레딧 B, $ 100 트랜잭션 커밋
이것은 다음과 같이 재 작업 될 수 있습니다.
/Transfer A, B, $100
In this way, the server might do this in two steps, but the action from the client is a single, atomic operation that makes logical sense.
I'm sure there are lots of examples where it is more convenient to do an all or nothing set of operations (and I'm curious what people can come up with to address them), but I usually rework things in this way.
A REST operation can start a transaction, perform multiple database or other transactional operations, then commit or rollback - all within the scope of a transaction.
What REST cannot do is to be other than the root of a transaction. You can't start a transaction, then perform two REST operations and a database operation, then commit them all together. That's just like the situation of ASMX web services in .NET. They can be the root of a transaction, but that's all. They were successful for years, until WCF was introduced, supporting WS-Transactions. Even today and using WCF, most web service operations do not need to be transactional in the sense you're asking about.
This is an interesting topic. As you mentioned, SOAP has this sort of functionality already, but it took many years before SOAP matured to the point where people would consider doing real security and transactions with it. Before that, it was CORBA.
The various high-grade extensions to SOAP, including security and transactions, took a lot of work by a lot of people to get them right. This isn't going to happen to REST overnight, and it may never happen at all.
I feel that much of REST's currently popularity is something of a backlash against poorly-designed and over-complicated SOAP implementations, which is a shame, because SOAP doesn't have to be like that. As with anything else, it needs good design to make it work nicely.
I think that transactions using REST are actually achievable. Think of a transaction as a resource which you can create (start), edit (post changes through), and delete (commit, roll back). Changes posted to the transaction wouldn't need to modify the global state until the transaction was committed, and during the commit, you could enforce any global state consistency rules you'd need to. The transaction resource would, of course, be protected through authorization rules.
You already mentioned the common illustration for this concept:
Now, I've read a specific argument a couple of times in my research, and its related to how we're supposed to think about transactions in REST, and the example given is the shopping cart, where you implicitly have isolation because the cart is YOURS.
However I disagree with this argument, firstly, the isolation a shopping cart has is merely convenient, this isn't a transaction isolation.. what happens if I'm simultaneously doing an operation against my cart whilst some part of my application is reading data from it? I wouldn't expect the reading part of my application to see data that is 'still in transaction'.
Why wouldn't you allow the viewing of the transaction? As long as you present it as what it is, a list of pending changes, it's actually helpful to provide that feature. But if you didn't want it to be viewable, you could disabling GET
on the resource.
Take a look at the OpenStreetMap API. I think it is kind of "REST" and it provides kind of "transactions" – called 'changesets' there. Is that what you need?
Actually, transactions in REST work in much the same way that transactions are supposed to work in traditional SOAP services.
RPC-style transactions, where the client issues a "begin transaction" command (or some operation that implicitly begins but does not commit a transaction), followed by some additional operations, followed by another implicit/explicit "end transaction" command, are antiquated. The Web Service world moved away from the RPC model a long time ago; RPC/encoded in SOAP is not even WS-I compliant!
Instead of procedures, SOAP services today are built around the concept of messages. A single message contains all of the information necessary to perform a complete transaction. If you are submitting an order, the OrderRequest
message will contain the customer information, order information, order details, payment details... everything that the server could possibly need to know about a single order.
We do have WS-Transactions that define semantics for distributed transactions, but these aren't really intended to support RPC-like semantics from the client, they're meant for orchestrations when you need to have several services participate in the same transaction. For example your order service needs to enlist a payment processing service to validate the credit card info and post a payment, which needs to be rolled back if the fulfillment service finds that you're out of stock, or something like that... you get the idea. This all takes place in the server environment so there's really nothing stopping you from doing the same thing in REST.
In REST, you have resources instead of messages, but the concept is really quite similar. Instead of an OrderRequest
message the client submits (PUT
) an Order
resource, and the resource should contain all the same information necessary to complete the transaction. Admittedly, if you're trying to perform complex orchestrations, you might find REST a bit unwieldy compared to SOAP, but that doesn't mean you can't keep using REST for your front-end, just that SOAP will serve you better for your back-end services.
The reality, though, is that 99% of the time, people don't need the complexity of WS-Transactions. I know this because I use SOAP (WCF) almost exclusively and rarely use WS-Transactions.
In REST, the "state" resides on the client. The server tells the client, "here is all the information you need to give me to create this resource (complete this transaction)." But this blank form doesn't actually begin a transaction. It's up to the client to actually provide the information - fill in the form, so to speak. What the client does while it is filling in the form is of no concern to the server; when the client finally sends the finished form to the server, it is validated in its entirety. It's similar to a Unit of Work, except that the client is the one keeping track of the "work".
Hope this gives a better idea of how transactions can be and are achieved over REST. They just rely on a richer message/resource concept and a form of optimistic concurrency.
Because not every system requires transactions.
I know of very successful online accounting systems (SaaS) which have a REST-based non-transactional API for creating, retrieving and manipulating invoices etc. They are widely acclaimed for their API and the ease of integration their system with other parties. The API is easy to maintain, usable from a variety of platforms and ensuring backwards compatability is reasonably straightforward.
The lack of transactions can be a real pain in the neck, but most of the time, when their servers aren't too loaded, the API works very well.
Sometimes, less-than-perfect is just good enough.
'Program Tip' 카테고리의 다른 글
Facebook Graph API를 사용하는 페이지 '좋아요' (0) | 2020.11.02 |
---|---|
사용하지 않는 포함 된 헤더를 찾는 도구? (0) | 2020.11.02 |
qmake 또는 Qt Creator없이 Qt를 사용할 수 있습니까? (0) | 2020.11.02 |
“git checkout -f”와“git reset --hard HEAD”의 차이점은 무엇입니까? (0) | 2020.11.02 |
NuGet 스크립트를 다른 디렉터리로 (0) | 2020.11.02 |