Edited at

apipie-rails で multipart/form-data を扱う

4年ほど乗っている5万円のクロスバイクのオーバーホールに本体代くらいの費用がかかりそうなのでいっそロードバイクに買い換えようか悩んでいるstreampackチームのminsuです。


やりたいこと

rails APIへ次のようなformを送ったときに、

apipie-railsのcustom validatorを設定してformのfileタイプをパラメーターとして扱えるようにします。

<form method="post" action="xxxx" enctype="multipart/form-data">

<p>画像ファイル<input type="file" name="imagefile" accept="image/*"></p>
<p><input type="submit" value="送信する"></p>
</form>

apipie-railsgem

https://github.com/Apipie/apipie-rails

apipie-railsは、railsの REST API向けのドキュメント生成のためのツールで、

次のようにアクションごとにエラーコードやパラメーターがドキュメント表示できます。

ss1.png


バリデーター

コードを記載するとドキュメント側に反映されるとともに、

apipie-railsがリクエストパラメータをチェックしてドキュメントで指定した以外のフォーマットの場合にバリデーションエラーを返すという機能が付いています。

バリデーターは型の指定や配列、ハッシュなどapipie側で使いやすいものがすでに用意されているのですが、formのfileタイプに対応できるバリデーターはありません。


カスタムバリデーター

しかし、apipieでは独自にバリデーターを設定することができるのでformのfileタイプを扱えるカスタムバリデーターを実装していきましょう。

https://github.com/Apipie/apipie-rails#adding-custom-validator

カスタムバリデーターは initializars で設定できるため、

config/initializars/apipie_validators.rb を作成して次のclassを設定します。


apipie_validators.rb

class UploadedFileValidator < Apipie::Validator::BaseValidator

def validate(value)
value.is_a?(ActionDispatch::Http::UploadedFile)
end

def self.build(param_description, argument, options, block)
self.new param_description if argument == :uploadedfile
end

def description
'Must be a valid file'
end

end


そしてapipieでパラメーターの記述で、さっきカスタムバリデーターで設定した :uploadedfile を指定してあげるとバリデーションチェックで ActionDispatch::Http::UploadedFile クラスなのかをチェックしてくれるようになります。

   param :imagefile, :uploadedfile, :required => true ,:desc => "Need to set a new user image file in form-data"

これでapipie-railsでformのfileタイプが扱えるようになりました。


おまけ

カスタムバリデーターを作らなくても次のようにパラメーターに直接 ActionDispatch::Http::UploadedFile クラスを指定することでも同じようなことができるのですが

   param :imagefile, ActionDispatch::Http::UploadedFile, :required => true ,:desc => "Need to set a new user image file in form-data"

ドキュメントの記述がこのように

ss2.png

Must be a ActionDispatch::Http::UploadedFileとなるので、ドキュメントを読む側がなんのこっちゃになりそうです。