1

RESTful アーキテクチャでは、POST リクエストはSafeでもIdempotentでもありません。

error現在、jQuery の ajax 呼び出しは、関数を使用して失敗をキャッチするように ajax 呼び出しを設定することで、失敗した要求を再試行し、オプションで呼び出しを再試行することができます (関連するtimeouttryCountretryAfterなどの設定と共にretryLimit)。

GET 呼び出しを再試行することは問題ではありませんが (どちらも安全冪等であるため)、POST 呼び出しを再試行するにはどうすればよいでしょうか?

たとえば、ajax POST を使用して新しいレコードを挿入するとします。

  1. クライアントで ajax POST 呼び出しが開始されます。
  2. 呼び出しはサーバーによって受信され、データベースが更新されます。
  3. サーバーは応答しますが、この応答はクライアントに配信されません。
  4. そのため、クライアントは失敗があったと想定し、呼び出しを再試行します。
  5. 呼び出しはサーバーによって再度受信され、別の変更が行われます。
  6. 等々...

このシナリオに対応する最善の方法は何でしょうか?

4

1 に答える 1

2

コードを簡単に休める唯一の方法は (ダジャレを許してください)、データが受信されて受け入れられたことを確認することです。

したがって、答えは実際には POST の性質によって異なります。名前を「John」に設定するなど、POST が本当に更新である場合は、確認が得られるまで何度か再試行しても問題ありません。

ただし、あなたが話しているのは、POST が REST の意味で実際に POST である場合です。つまり、通常、新しい行が追加されます。その場合、適切な方法は、クライアントとサーバー間のより深いハンドシェイクに依存します。

最終的に、データの整合性は、データベースを処理するコード、つまりサーバー コードの仕事です。したがって、行を複製してはならない場合、シナリオは次のように進みます。

  • クライアントは、クライアントが生成した ID を含む「送信トークン」の GET を作成します。
  • サーバーは clientID に基づいて送信トークンを生成し、それをテーブルに格納します
  • サーバーはトークンをクライアントに送信します
  • クライアントは、トークンを含む POST を送信します。
  • サーバーはトークンを受け取り、それを検証し、投稿を挿入し、成功で応答します

    1. そのため、GET トークン リクエストがサーバーに到達しない場合、クライアントは常に同じ clientID を使用して再度リクエストできます。
    2. クライアントが最終的にトークンを取得した場合、クライアントはサーバーに要求の記録があり、フォローアップ POST を期待していると見なすことができます。
    3. いくつかの失敗の後、クライアントが複数のトークン応答を取得することになった場合、それらはすべて同じトークンになります。
    4. そのため、クライアントは POST し、成功を受け取るまで (トークンを使用して) 投稿を続けます。
    5. サーバーが投稿のいずれかを取得すると、データを挿入してトークンを無効にし、成功を返します。
    6. サーバーがリクエストを受け取り、すでにトークンを使用している場合、サーバーは「重複したリクエスト」で応答します。
    7. クライアントは 1 つの「成功」しか受信できず、クライアントがたまたまそれを受信しなかった場合、その後の試行で「重複した要求」を取得し、それが挿入されたことも認識します。

サーバーが重複を気にせず、それを制御できず、それがクライアントだけである場合、最善の解決策は、再試行する前に長い間待機し、常に get と post を交互に行うことです。サーバーがオフラインのときにリクエストを収集するキューがあり、来週それらを処理する可能性があるため、理論的にはわかりません。

于 2015-08-12T18:13:12.017 に答える