[解決済み】REST API - ファイル(画像)処理 - ベストプラクティス
質問
REST APIでJSONを受け渡しするサーバーを開発しています。問題は、クライアントからサーバーに画像をアップロードする必要がある場合です。
注:また、エンティティ(ユーザー)が複数のファイル(carPhoto、licensePhoto)と他のプロパティ(名前、メール...)を持つことができ、新しいユーザーを作成するときに、これらの画像を送信せず、登録プロセスの後に追加されるという使用例について話しています。
私が知っている解決策は、それぞれいくつかの欠点があります。
1. JSONの代わりにmultipart/form-dataを使用する
良い : POSTとPUTリクエストは可能な限りRESTfulで、ファイルと共にテキスト入力を含むことができます。
コンサ : JSONではないので、multipart/form-dataと比較して、テストやデバッグなどがはるかに簡単です。
2. 別ファイルの更新を可能にする
新しいユーザーを作成するためのPOSTリクエストは、画像を追加することができません(これは、私が最初に言ったように、私たちのユースケースでは大丈夫です)、画像のアップロードは、例えば/users/4/carPhotoへのmultipart/form-dataとしてPUTリクエストで行われます。
良い : すべて(ファイルのアップロード自体を除く)がJSONのままなので、テストやデバッグが簡単です(長さを気にせずに、完全なJSONリクエストを記録できます)。
短所
: 直感的ではありません。一度にエンティティのすべての変数をPOSTまたはPUTすることはできませんし、またこのアドレスは
/users/4/carPhoto
は、むしろコレクションとして考えることができます(REST APIの標準的なユースケースは次のようなものです)。
/users/4/shipments
). 通常、エンティティの各変数をGET/PUTすることはできません(したくもありません)。GETでnameを取得し、PUTでusers/4に変更することができます。idの後に何かがある場合、それは通常、users/4/reviewsのような別のコレクションです。
3. Base64を使用する
JSONで送るが、ファイルはBase64でエンコードする。
良い : 最初のソリューションと同じで、可能な限りRESTfulなサービスです。
コンサ : もう一度言いますが、テストやデバッグが非常に難しくなります(本体が数メガバイトのデータを持つこともあります)。
2の解決策をぜひ使いたいのですが、欠点もありますし...。どなたか、より良い洞察力をお持ちの方はいらっしゃいませんか?
私の目標は、できるだけ多くの標準が含まれたRESTfulなサービスを提供することであり、一方でできるだけシンプルでありたいと考えています。
解決方法は?
OPはこちら (私は2年後にこの質問に答えています。ダニエル・セレセドの投稿は当時は悪くなかったのですが、ウェブサービスは非常に速く発展しています)
フルタイムのソフトウェア開発を3年間続けた結果 (ソフトウェアアーキテクチャ、プロジェクト管理、マイクロサービスアーキテクチャにも重点を置いて)私は間違いなく2番目の方法(ただし一般的なエンドポイントは1つ)を最良の方法として選択します。
画像用の特別なエンドポイントがあれば、その画像を扱うのにはるかに大きな力を発揮します。
モバイルアプリ(iOS/android)とフロントエンド(Reactを使用)の両方で、同じREST API(Node.js)を使用しています。これは2017年のことで、画像をローカルに保存するのではなく、クラウドストレージ(Google cloud、s3、cloudinary、...)にアップロードしたいため、画像に対する一般的な処理をしたいのです。
私たちの典型的なフローは、画像を選択するとすぐにバックグラウンドでアップロードを開始し(通常/imagesエンドポイントにPOST)、アップロード後にIDを返すというものです。なぜなら、ユーザーは画像を選択した後、他のフィールド(住所、名前など)を入力するため、送信ボタンを押したときにはすでに画像がアップロードされていることが多いからです。アップロード中...」と表示されるのを待つ必要はないのです。
画像の取得も同様です。特に携帯電話や限られたモバイルデータのおかげで、オリジナルの画像を送るのではなく、リサイズした画像を送りたいので、それほど帯域幅を取りません(モバイルアプリを高速化するために、リサイズは全くせず、表示に完全にフィットする画像が欲しい場合もよくあります)。このため、良いアプリはcloudinaryのようなものを使用しています(または、リサイズ用に独自の画像サーバーを用意しています)。
また、プライベートなデータでなければ、アプリやフロントエンドにURLを送るだけで、クラウドストレージから直接ダウンロードされるので、サーバーの帯域幅と処理時間が大幅に節約できます。大規模なアプリでは毎月何テラバイトものデータがダウンロードされますが、CRUD操作に重点を置いているREST APIサーバーのそれぞれで直接処理するのは好ましくありません。そのような場合は、1つの場所(キャッシュ機能などを備えた画像サーバー)で処理するか、クラウドサービスにすべてを任せます。
短所: 唯一の欠点は、「画像が割り当てられない」ことです。ユーザーは画像を選択し、他のフィールドに入力し続けますが、その後、「いやだ」といってアプリやタブを閉じますが、その間、画像は正常にアップロードされています。これは、どこにも割り当てられていない画像をアップロードしてしまったことを意味します。
これにはいくつかの対処法があります。最も簡単な方法は、「気にしない」です。このようなことがあまり起こらない場合や、ユーザーが送ってきたすべての画像を保存しておきたい場合(理由は問いません)、削除したくない場合に有効な方法です。
もうひとつは簡単で、CRON を使って毎週、1週間以上前の未割り当ての画像をすべて削除します。
関連
-
[解決済み] Golang json Unmarshal "予期せぬJSON入力の終了"
-
[解決済み] JSONCとは何ですか?JSONCとJSON-Cは違うのですか?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] JSONPとは何か、なぜ作られたのか?
-
[解決済み] RESTful WebServiceにファイルや関連データをJSONで投稿する。
-
[解決済み] バイナリデータをJSON文字列で。Base64より優れたもの
-
[解決済み】REST APIでのPUTメソッドとPATCHメソッドの使い分け 実生活でのシナリオ
-
[解決済み】新しいPostgreSQL JSONデータ型内のフィールドを変更するにはどうすればよいですか?
-
[解決済み】RESTウェブサービスを使用して、メタデータを含むファイルをアップロードするにはどうすればよいですか?
-
[解決済み】ECMAScript 6でJSONファイルをインポートする方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] UnicodeDecodeError: 'utf8' コーデックは位置3131のバイト0x80をデコードできません: 不正なスタートバイトです
-
[解決済み] JSONとJSONPの違いは何ですか?
-
[解決済み] tsconfig.jsonは何のためにあるのですか?
-
[解決済み] PandasのDataFrameをJSON形式に変換する
-
[解決済み] BSONとは何ですか?JSONとどう違うのですか?
-
[解決済み] RESTful WebServiceにファイルや関連データをJSONで投稿する。
-
[解決済み】GoでPOSTリクエストでJSON文字列を送信する方法
-
[解決済み] node.jsでjsonのためのrequireはありますか?
-
[解決済み】JSONのキーは引用符で囲む必要があるのでしょうか?
-
[解決済み】JSON文字列を構築する際に、特殊文字をエスケープする方法は?