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

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

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

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=example1

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=get

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=query_parameter

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

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

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

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=post

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart1

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart2

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart3

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart4

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

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

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart5

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

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

daipresents

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

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

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

https://gist.github.com/daipresents/528891497cc6e89f5c06e597a8dcc2e1.js?file=multipart6

よかったよかった。

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

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください