2011-02-22 13 views
45

ユーザーが提供したデータを受け入れるサービス用のREST APIを作成しています。私はすべての操作を完全に非同期にしたいと思います。これには、PUT、POST、DELETE、おそらくGETリクエストが含まれます。私の考えは、要求を受け取り、それが有効な要求であることを保証するのに十分なほど処理し、その後、データが最終的に利用可能なURLおよび後続の要求が処理されたデータと照合できるようにHTTP 202受け入れられた応答を渡す。要求が無効であれば、HTTP 400を送信します。非同期操作にhttpステータス202を使用します。

クライアントは、今後、私がそれらを提供したURLをチェックし、トークンを渡す責任があります。データが利用可能な場合、私は通常の200または201を返しますが、まだリクエストを処理している場合、処理が完了していないことを示す別の202を送信します。データの処理中にエラーが発生した場合は、必要に応じて4xxまたは5xxステータスを送信します。

これは、すべての有効なリクエストをリクエストプールにダンプし、ワーカーがキューから取り出してリクエストを処理できるようにするためです。利用可能なプールのサイズや人数はわからないので、Google App Engineの30秒制限を満たすのに十分な速さでリクエストを受け取ることはできません。

私の質問は次のとおりです。このようにリクエストを処理してRESTを歪めていますか?たとえば、ブラウザは要求に即座に応答する必要があるようです。私のHTMLページでは、構造化ページで応答し、AJAXを使用してデータ要求を処理する予定です。

私は、このようにRESTを使用してデータを処理する際の意見や経験にほとんど関心があります。

+0

あなたはブラウザが直接これを使用することを期待していますか?このソリューションはAPI(@systempuntooutの答えを参照)にとってはうまくいくようですが、明らかにウェブブラウザでは機能しません。 –

+0

私は、ブラウザにGET操作を制限し、最も可能性の高いクエリをメモリに保持しています(memcachedなど)。任意の長期クエリは、AJAXを介してポーリングを使用して表示されます(例えば、大きな結果セットをフィルタリングする)。 PUTとPOSTはおそらく、サーバーがタスクを完了するまで、ユーザーに標準の「メディアが処理されています」というメッセージを与えるYouTubeビデオのアップロードと似ています。 –

+0

いくつかのrestapiのリソースhttp://stackoverflow.com/questions/14124056/rest-api-202-versus-204/27766943#27766943 –

答えて

29

私はあなたのソリューションは大丈夫だと思い、Http status 202は、要求が処理のために受け入れられているが、処理がを完了していないことを示す。この特定のケースで使用するproper responseです。

あなたのワークフローで少し変更するものは、後続のリクエストのHttp statusです。

このように、202 responseは、Location headerを返して、クライアントが以前のリクエストのステータスを監視するために使用するURLを指定する必要があります。
代わりに、保留中のプロセスの場合には202を返すので、このチェックイン・ステータスの-私のプロセス URLを呼び出すと、私は戻ってくる:

  1. 200 OK要求されたプロセスがまだ保留されている場合。レスポンスには、プロセスの保留状態を記述する必要があります。
  2. 201 Created処理が完了したとき。 GET/PUT/POSTの場合の応答には、要求された/作成された/更新されたリソースへのロケーションが含まれている必要があります。
+1

私はあなたのステータスへの回答に同意します。私はまだ「要求が成功しました」と示唆しているので、まだ処理中に200 OKを送信するのは少し面倒です。しかし、202は、要求が受け入れられたことを示唆しています。これは、進捗状況を確認しているときではありません。私が何を望んでいるのかを正確に記述することはできないので、200は「これほど良い」という立場に立つことができます。 –

+12

私はこれに同意しますが、私は「201」または「202」のいずれかがフォローアップ要求に意味をなさないと思います。ステータスコードは、リクエスト/レスポンスのステータスを示すためのもので、リソースではありません。フォローアップ要求に「200」を貼り付け、その表現を使用してリソースの状態を表します。 –

+0

サンプルコードはありますか? – plzdontkillme

21

古い質問に自分の2セントを追加します。私の考えは、systempuntooutやAvi Flaxの提案と似ています。

Locationヘッダーを介して別のリソースにリダイレクトすると、応答が最初の要求に適切であることに同意します。

私はLocation URLはおそらくあなたがLocationリダイレクトの共通の期待に合致するように参照するトークンを含めるべきだと思います。例えば、Location: /queue?token={unique_token}またはLocation: /task/{unique_token}です。

「ステータスの確認」の操作が成功した場合(現在の要求が「受け入れられた」ことを意味するHTTP 202ではない)、プロセスの状態を確認するために使用されるリソースはHTTP 200応答を返す必要があります。

しかし、私は新しいエンティティが作成されたときに「ステータスをチェックすると、」それが作成された後、新たなエンティティのためのLocationヘッダとHTTP 303See Other)レスポンスを返すべきだと思います。これは、GET要求がステータスの確認のために実行されただけで何も作成されなかったため、HTTP 201を送信するよりも適切です。

ステータスを確認するために使用されるリソースは、エラーコードを適切に返す必要があります。 「状態をチェックする」が正常に実行されるたびに、適切な成功コードが返されます。アプリケーションレベルでエラーを処理することができます(応答本体をチェックすることによって)。

+0

私は303リダイレクトを使用して、クライアントが別のURLでリクエストを完了するように考えています。あなたがリンクしているウィキペディアのページを見ると、まさに私の本来の目的のためのその使用方法が説明されています。応答していただきありがとうございます。 –

6

これは本当に古い質問ですが、私は正解ではないと主張していますが、私の考えは少し違っています。クライアントの観点

から

はのは、最初のHTTPリクエストから始めましょう。まず第一に、リクエストはPOSTでなければなりません。リソースを作成するために、サーバーにメッセージを送信しています。 GETやPUTので、この場合には有効ではありません:GETは、リソースを取得するためのものですので、GETはあなたではないので、PUTが有効ではありません

  • 特定の場所で、このコンテキストでは有効ではありません

    • 要求を作成すると、要求を作成するようにサーバーに要求しています。サービスの観点

      から

  • は、だから今は、要求を処理するために、サーバーにPOSTを送信しています。サーバは、(の4xxと5xxのエラーを含めない)、実際に3可能な戻り値を持っています

    • 「作成した201は、」サービスが要求を持って、すぐにそれを処理することができたことを示している、または許容可能な時間内に。この期間は完全にサービス設計に依存します。これを定義するのはサービス開発者次第です。
    • "202 Accepted"は、サービスが要求を受け取り、処理していることを示します。これは、サービスが何らかの時間がかかることが分かっている場合に使用されます。もう1つの視点は、サービスが結果を決定する方法がない他の非同期操作に依存している場合、サービスは "202 Accepted"応答を返す必要があるということです。最後に、サービス設計者の中には、できるだけ迅速に "202 Accepted"を返すものもあります。
    • "302 Found"が表示されることがあります。これは、通常、サービスがすでに存在する(まだ有効であり、エラー状態ではない)リソースを生成しているとしてリクエストを識別でき、既存のリソースを再利用することが許容できる場合です。すべてのサービスがこのように動作するわけではありません。スレッドにコメントを投稿すると、常に新しいリソースを作成する必要があります。他のサービスは:医師のリストを取得する基準のセットを投稿すると、医師の同じリストを生成します。この情報を再利用できる場合は、再利用してください。
    • これらすべての応答では、リソースが見つかる場所を含む「Location」HTTPヘッダーがクライアントに返されます。これは重要であり、後で見るように、一部の人々がアプローチにばらつきがちである場合があります。リソースが他の要求と再利用できる場合、同じ要求が常に同じURLを生成するように、「場所」を実際に生成する必要があります。これにより、多くのキャッシングと再利用が可能になります。

    サービスが要求を正常に完了すると、クライアントに返された場所にリソースが作成されます。

    ここで私は上記の応答とは少し違うものを見ています。

    サービスが要求を完了できない場合でも、クライアントに返された場所にリソースが作成されます。このリソースは、失敗の理由を示す必要があります。 HTTPプロトコルに靴をつけるよりも、リソースに障害情報を提供する方がずっと柔軟です。

    サービスが完了する前にこのリソースの要求を取得した場合、「404 Not Found」が返されます。私が "404 Not Found"にすべきだと思うのは、本当に存在しないからです。 HTTP仕様では、「404 Not Found」は、リソースが存在しない場合にのみ使用でき、現時点では存在しないと言います。私の意見では、このタイプの非同期ポーリングフローに対する応答は完全に正しいです。

    リソースのみ一定時間があることになっているときのシナリオもあります。例えば、夜間にリフレッシュされるソースに基づくデータであってもよい。このような場合には、リソースを削除する必要がありますが、 "410 Gone"ステータスコードを返すために知ることができるインジケータをサービスに提供する必要があります。これは、基本的には、リソースがここにあったが、もはや利用可能ではない(つまり、期限切れになっている可能性がある)ことをクライアントに伝えています。クライアントからの典型的なアクションは、要求を再送信することです。クライアントの観点から

    クライアントが応答を取得する場合、それは最初の投稿のために再度

    、それは「場所」を取得し、GETを使用して、そのURLを使用してサービスへの要求を行う(再び、投稿しません)。サービスは一般的に次の値で応答します。

    • "200 OK"は要求が完了したことを示します。要求の結果はコンテンツ本文に返され、Accept HTTPヘッダーで定義された形式でコンテンツが提供されます。
    • 「404見つかりません」というリクエストがまだ完了しなかったことをクライアントに言うだろう、リソースがまだ存在していない、そして、この場合には、それは基本的に後でもう一度試してみてください。
    • クライアントが長期間に渡ってリソースを取得しようとする可能性があり、もはや存在しない場合、「410 Gone」が返されます。この場合、元のクエリを再送信するだけです。

    返されるリソースは、一般的に成功と失敗の応答を定義できる形式であることが指摘されています。クライアントは、エラーがあった場合、それが何であったか、それに応じて対応できるかどうかをこのリソースから判断することができます。そのサービスの有効期限が切れると、時間の短い期間の後、エラーリソースが削除されますので、

    また、サービス開発者はそれを行うことができます。

    これは私の考えです。パーティーは非常に遅いですが、今後の読者にはよくある質問とは若干異なる見方があることがあります。

    +3

    404の問題は、それがキャッシュ可能であることです。 (http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-25#section-6.1を参照)。 404が成功するまで404を再試行すると、使用するのに良いパターンではなく、非常に非標準的なようです。 4xxエラーは特にクライアントエラーです。 4xxエラーは、クライアントが間違いを犯したか、リソースにアクセスするために必要な情報を渡すことができなかったことを意味します。通常の使用では、404に解決されるLocationヘッダーを取得することはバグです。 (競合状態やデータベースの一貫性の問題など) – ngreen

    +2

    良い点。キャッシュ可能な問題は、キャッシュ制御HTTPヘッダーによって解決できます。第2の点に関しては、それは良い点です。技術的には、404の誤った使用ではありませんが、あなたは有効な懸念を提起します。 –

    +1

    Content-Locationヘッダーを使用して操作のステータスを取得することを検討できます。それ以外の場合、私はDinoに同意します。 Content-Locationのインスピレーションは、Microsoft Azureにあります。https://docs.microsoft.com/en-us/rest/api/hdinsight/asynchronous-operations--202-accepted-and-location-header- –

    1

    FWIWでは、Microsoft Flowはこのようなパターンを使用します。
    最初の呼び出しでは、場所ヘッダー付きの202が返されます。 フォローアップ呼び出しでは、次のいずれかが返されます。 1.まだ処理していない場合 - > 202の場所ヘッダー。 locヘッダーは異なる場合があり、呼び出し間で状態を渡す方法を提供します(潜在的にサーバーをステートレスにします)。 2.行われた場合 - で> 200

    詳細:https://github.com/jeffhollan/LogicAppsAsyncResponseSample

    関連する問題