2012-04-17 17 views
5

POST(または他の非冪等動詞)が成功するかどうかを判断するためのRESTfulな方法はありますか?これは本質的に、異なるサービスに対して複数の冪等の要求を行う必要がある場合に有用であるように思われます。これらの要求を「トランザクション」(つまりロールバックのサポート)で実行できるのはいいですが、これは不可能なので、実際に実行する前に各要求が成功するかどうかを確認することです。POSTが成功するかどうかを判断するためのRESTfulな方法はありますか?

たとえば、カスタムテキストが印刷されたTシャツを購入できる電子商取引システムを構築しているとします。このシステムでは、Tシャツ印刷サービスと支払いサービスの2つのサービスを統合する必要があります。これらのそれぞれにはRESTful APIがあり、いずれかが失敗する可能性があります。 (例えば、印刷会社が特定の言葉をTシャツに印刷することを拒否したり、クレジットカードの有効期限が切れた場合、銀行はクレームを提出する可能性があります)。これら2つのリクエストを投機的に実行する方法はありますか?両方のリクエストが有効であると思われる場合

もしそうでない場合は、この問題を別の方法で解決できますか? POSTでリソースを作成してstatus = pendingとし、すべてのリクエストが成功した場合はstatus = completeに変更しますか? (DELETEはもっと厄介です...)

+0

もう1つのアプローチ: 'persist = false'または' ephemeral = true'の 'POST'です。 (ちょっとハッキリしていますが、 'status'の変更は必要ありません。本当に' POST'が起きたければ、再度発行してください。) – mjs

答えて

2

HTTPはまさにあなたのシナリオに202のステータスコードを定義しています

202受理

要求が処理のために受理されたが、処理は完了していません。要求が実際に処理されたときに許可されない可能性があるため、要求は最終的に実行されるか、または実行されない可能性があります。このような非同期操作からステータスコードを再送信する機能はありません。

202応答は意図的にコミットされません。その目的は、サーバへのユーザエージェントの接続がプロセスが完了するまで持続することを必要とせずに、サーバが何らかの他のプロセス(おそらく1日に1回だけ実行されるバッチ指向のプロセス)の要求を受け入れることを可能にすることです。このレスポンスで返されたエンティティは、リクエストの現在のステータスとステータスモニタへのポインタの表示、またはユーザがリクエストが実行されると予想できる何らかの見積りを含めるべきです(SHOULD)。

出典:HTTP 1.1 Status Code Definition

これはあなたが要求が完了していないと、エンティティがまだ作成されていないことを示すされていることを除いて、作成された201と同様です。あなたのレスポンスには、 "order request"を表すリソースへのURLが含まれているので、クライアントはこのURLを通じて注文のステータスを確認できます。


より直接あなたの質問に答えるために:あなたはそれを作る前に、あなたは千里眼のために求めているので、要求は、成功するかどうかを「テスト」に方法はありません。

今後リクエストを試みるときに発生する可能性のある技術的な問題の範囲を予測することはできません。ネットワークが利用できない、サーバーが機能するために依存するデータベースまたは外部システムにアクセスできない、電源切断があり、サーバーがオフラインになっている、迷子なニュートリノがあなたのメモリに迷って0になる可能性があります1に致命的なカーネル障害を引き起こします。

リモートサービスを使用するには、他のプロセスと分離して要求が失敗する可能性があることを考慮する必要があります。

あなたの特定の問題については、サービスにトランザクション上の安全性がない場合は、そこでは何も焼くことができず、これをより現実的な方法で処理する必要があります。私の頭の上からいくつかのオプション:

  1. あなたは彼らが実際にそれを配置することなく、任意の注文を処理するでしょうかどうかを確認することができますので、あなたの「テスト」のメカニズムを与えるためにTシャツの会社を取得します。それらを使用して注文することは、2段階の操作であり、最初の段階(その時点で作成を検証する)で注文を作成し、その後、注文を処理するよう依頼することができます成功)。

  2. 最初にクレジットカードによるお支払いを行い、ご注文を「有料」の状態に移行させてください。その後、非同期プロセスとしてTシャツサービスで注文を実行しようとします。フルフィルメントが失敗し、顧客が何か印刷物を手に入れようとしたことが分かった場合、その会社は生産準備ができていないので、注文を変更したり払い戻しをしなければなりません。

ほとんどの組織では、技術的にシンプルでビジネスリスクが低いため、2番目のアプローチを採用します。また、Tシャツのサービスが利用できないことに対処できるという利点もあります。非同期プロセスはサービスが利用可能になるまで単に待機し、その時点で注文を完了します。

+0

+1。興味深いことに、202コード... –

+0

申し訳ありません、私は "non-idempotent"を意味しました(質問は更新されましたが、これについてもう一度考えていますが、質問はPUTにも当てはまります...)。とにかく、私は202が私の目的に合っていないと確信しています。それは、クライアントが望むものとは無関係に*サーバー*によって発行されたものです。 (おそらく、顧客は有効なクレジットカードを持っていないため、Tシャツを購入することはできません。) – mjs

+0

idempotencyで私の言葉を削除しました。 –

1

正確に。それはあなたが最後の文章で示唆するようにすることができます。アイデアは、「受注」の「進行中の要求」を表すリソースの作成を中断することです(ネットワークの障害がなければ常に機能します)。 POSTは「Location」ヘッダーを返すので、リクエストの「ステータス」をいつでも取得できます。

ある時点で、受け入れられるか拒否されることがあります。これは当然のことかもしれないし、時間がかかるかもしれないので、あなたはこれらの制限を使ってサービスを設計しなければなりません(すなわち、顧客が注文を受け入れるかどうかをチェックするか、 。

関連する問題