web-dev-qa-db-ja.com

RESTfulな大きなファイルのアップロードを実装する適切な方法

私はREST APIを作成してしばらく経ちますが、大きなファイルのアップロードという1つのケースでまだバグがあります。Googleドライブ、Twitterなど、他のいくつかのAPIを読んだことがあります。と他の文献、そして私は2つのアイデアを得ましたが、それらのいずれかが「適切」であるかどうかはわかりません。適切なように、それはある程度標準化されていることを意味します。クライアントロジックはあまり必要ありません(他の当事者が実装するため)そのクライアント)、またはさらに良いことに、cURLで簡単に呼び出すことができます。計画は、Java、できればPlay Frameworkで実装することです。

明らかに、ファイルが大きいため、ファイルのパーティション分割とサーバー側のバッファリングメカニズムが必要になります。

だから、私が得た最初の解決策はマルチパートアップロード(_multipart/form-data_)です。私はこのようにして、以前にこのように実装しましたが、特にクライアントがファイルキー名を設定する必要があるため、クライアント側でフォームを実際にエミュレートすることは常に奇妙です。クライアントがちょっと忘れたり、理解していないこと。また、チャンクサイズ/パーツサイズはどのように決まりますか?クライアントがファイル全体を1つのチャンクに入れないようにするにはどうすればよいですか?

ソリューション2、少なくとも私が理解したことですが、実際の実装実装を見つけることなく、「通常の」POST要求が機能する可能性があります。コンテンツはチャンク化され、サーバー上のデータがバッファリングされます。ただし、これが適切に理解されているかどうかはわかりません。データは実際にどのようにチャンクされますか、アップロードは複数のHTTPリクエストにまたがるか、またはTCPレベルでチャンクされていますか?_Content-Type_?

結論として、これらの2つ(または何か他のもの)は、クライアントフレンドリーで広く理解できる方法で、RESTファイルアップロード用のAPIを実装しますか?

マルチパートファイルのアップロードに対するAmazon S3 Rest APIのソリューションを確認することをお勧めします。ドキュメントは here にあります。

Amazonが使用する手順を要約すると:

  1. クライアントはマルチパートアップロードを開始するリクエストを送信し、APIはアップロードIDで応答します

  2. クライアントは、各ファイルチャンクをパーツ番号(ファイルの順序を維持するため)、パーツのサイズ、パーツのmd5ハッシュ、アップロードIDとともにアップロードします。これらの各要求は個別のHTTP要求です。 APIは、クライアントが提供したmd5ハッシュに対して受信したmd5ハッシュチャンクをチェックすることでチャンクを検証し、チャンクのサイズはクライアントが提供したサイズと一致します。 APIは、チャンクのタグ(一意のID)で応答します。 APIを複数の場所にデプロイする場合は、チャンクを保存し、後で場所に透過的な方法でそれらにアクセスする方法を検討する必要があります。

  3. クライアントは、APIから受信した各チャンク番号と関連するチャンクタグ(一意のID)のリストを含むアップロードを完了するためのリクエストを発行します。 APIは欠落しているチャンクがないこと、およびチャンク番号が正しいチャンクタグと一致していることを検証してから、ファイルをアセンブルするか、エラー応答を返します。

Amazonは、アップロードを中止し、アップロードに関連するチャンクをリストするメソッドも提供しています。アップロードが特定の時間内に完了しない場合、チャンクが破棄されるアップロードリクエストのタイムアウトを検討することもできます。

クライアントがアップロードするチャンクサイズの制御に関しては、クライアントがアップロードを分割することを決定する方法をあまり制御できません。アップロードに最大チャンクサイズを設定することを検討し、最大サイズより大きいチャンクを含むリクエストに対してエラー応答を提供することができます。

この手順は、REST APIで大きなファイルのアップロードを処理するために非常にうまく機能し、ファイルのアップロードに関連する多くのEdgeケースの処理を容易にします。残念ながら、私はまだライブラリを見つけていませんこれにより、これを任意の言語で簡単に実装できるため、ほとんどすべてのロジックを自分で作成する必要があります。

7
crawfobw

https://tus.io/ は、チャンクアップロードとタイムアウト後のアップロードの再開に役立つ再開可能なプロトコルです。これはオープンソースの実装であり、すでにさまざまな言語でさまざまなクライアントとサーバーの実装があります。

2
Jiss Raphel