Rubyのrest-clientを使ってmultipart/form-dataでファイルアップロードする

感想おまちしてます!

公式ドキュメントを読むだけではわからず、結局ソースを読んで調べたのでメモ。単純なファイルアップロードはサンプルがあったのですが、パラメタ付きで送る方法はサンプルとは違う方法しかないっぽい。

Rubyのクライアントはいろいろあるみたいだけど、今回はrest-clientを利用。

https://github.com/rest-client/rest-client

基本的な使い方はこんな感じ。RestClient.getRestClient.postのように簡単にリクエスト送信できる。

payload(日本語で貨物とか搭載量とか。ここではデータ本体という意味らしい)にいろいろ突っ込んで使うのが基本。

よくある使い方例。まずはシンプルにgeturlを叩く。

クエリパラメタを付与する場合。以下の例だとURLの末尾に?accept=jsonがつく。

パラメタはネストも可能。payloadを以下のように書くと・・・

:user => {:name => "daipresents"}

以下のようなフォームにdaipresentsが入力されているという意味になる。

<input name="user[name]" value="daipresents" />

postも簡単。以下はjsonを詰め込んで送る例。

問題はファイルをアップロードしたい場合。ドキュメントにはこの例が書かれている。

こう書くと:transfer:uploadの2ファイルをアップロードするという意味になる。試してないけどファイルはファイルオブジェクトでもパスでもいいみたいね。

multipartで送るケースは以下の感じ。

ファイルがないけどmultipartで送りたいときは、以下のようにmultipartパラメタをつけてあげる。

Basic認証情報をつける場合は以下。参考したのは「Ruby rest-client file upload as multipart form data with basic authenticaion

問題は、ファイルアップロードするときにクエリパラメタをつける場合。多分、このケースだとRestClient.postメソッドは使えない。

例えば、上のようにmyfileという名前で、image.jpgファイルを送る場合、リクエストに以下のようなフィールドが必要になる。

Content-Disposition: form-data name="my file" filename="image.jpg"

たとえば、こんな感じで書いてみると

Content-Dispositionフィールドはこうなる。

Content-Disposition: form-data; name="name"

daipresents

payload.rbがこの辺を頑張ってくれるんだけど、パラメタ全部をファイル情報としか扱ってくれない実装に見える。

となると、URL部分にパラメタを自分でつけるしかなさそうだけど、「[RoR]rest-clientでpaperclipに対応した画像フォーム送信を再現してみる」を読んでいてRestClient::Requestならいけそうなことがわかった。

実際にできた例はこちら。

よかったよかった。

同じpayloadのはずなんだけど、正しい書き方があるのかもしれない。