背景
ファイルアップロード用のWebAPIを設計するにあたって、いくつかのサービスを調査したのでまとめてみた
※今回は分割アップロードは考慮しない
調査結果
下記3種類に分かれる。(例外あり)
- リクエストボディにそのまま入れる
-
base64へ変換 -
multipart/form-dataにて送信
リクエストボディにそのまま入れる
Content-Typeにてファイルフォーマットを指定し、リクエストボディにデータをそのまま詰める
メリット:シンプル、分かりやすい
デメリット:パラメータをどのように設定させるか検討する必要あり(HTTPヘッダー、URLパス)
事例
Microsoft(OneDrive, SharePoint Online)
ファイル自体はそのままリクエストボディに入れる。ファイル名はURLのパスを使って指定する
PUT /me/drive/root:/FolderA/FileB.txt:/content
Content-Type: text/plain
The contents of the file goes here.
Google Drive(Simple Upload)
Google DriveはSimple UploadとMultipart Uploadの2種類が存在する(resumableは分割アップロードなので今回は対象外)が、Simple Uploadの方式
ファイル名等のパラメータ設定はアップロード後に別のAPIを叩いて修正する
Dropbox
Dropbox-API-ArgというHTTPヘッダー内にパラメータを設定する
base64へ変換
ファイルをbase64に変換して、リクエストを送る
メリット:JSON形式で送ることが出来る
デメリット:base64に変換する分、ファイルサイズが大きくなる(下記リンク参考)
事例
Microsoft(Exchange Online)
JSONのcontentBytesにbase64に変換したファイルを入れて送信する。ファイル名等もJSONの別のキーに一緒に詰めて送信する
POST https://graph.microsoft.com/v1.0/me/messages/AAMkpsDRVK/attachments
Content-type: application/json
{
"@odata.type": "#microsoft.graph.fileAttachment",
"name": "smile",
"contentBytes": "R0lGODdhEAYEAA7"
}
SmartHR
JSON内にbase64で変換したファイルを詰める。multipart/form-dataを採用しなかった理由まで下記に書かれている
multipart/form-dataにて送信
multipart/form-data形式でファイル自体やパラメータを詰めて送信する。詳細は下記
メリット:データをそのまま送れる(base64変換のように容量が余計に大きくならない)
デメリット:他のAPIがJSON形式の場合、アップロードAPIだけ形式が変わってしまう
事例
Box
multipart/form-data形式で送信する。その他のパラメータはattributesという属性内にJSON形式で値を入れる
サイボウズ
filenameにファイル名を入れて送信する(RFC準拠)
//Sample
X-Cybozu-Authorization: cnlvX2Z1a3VkYTpjeWJvenU=
Authorization: Basic QWRtaW5pc3RyYXRvcjpjeWJvenU=
Content-Type: multipart/form-data; boundary=---------------------------bee48a285354
Content-Length: 215
-----------------------------bee48a285354
Content-Disposition: form-data; name="file"; filename="users.csv"
Content-Type: text/csv
User1,User1,User1,password
-----------------------------bee48a285354--
例外:multipart/relatedにて送信
Google DriveのMultipart Uploadで利用されている
multipart/form-dataのようにメタデータも一緒に送信することが可能
ファイルアップロードAPIとしては、Google Drive以外ではあまり採用されていない
まとめ
個人的な偏見も含まれているが、下記のようにまとめた。大きいサイズのファイルアップロードを必要とする場合は分割アップロードのAPIが必要になってくると思われるので、どれを選んでもそこまで間違った選択にはならないだろう。
- リクエストボディにそのまま入れる
- たくさんのパラメータ設定を必要としない場合
-
base64へ変換- JSON形式にしたい場合
-
multipart/form-dataにて送信- 上記以外の場合
追加情報
関連記事に下記もありましたので、こちらもご覧ください。