素敵なサムシングを独断と偏見で一方的に紹介するブログ(´・ω・`)

IT

【bindFromRequestData】playFramework2.7で配列をマッピングする方法【BeanValidator】

投稿日:

スポンサーリンク

336×280




配列クエリをFormモデルにバインドしようとしたら一癖あった話

PlayFrameworkを使ってAPI開発をしている際に、配列を想定しているクエリパラメーターに対してもBeanバリデーションを行いたかったため、Formモデルを使ってマッピングしようとしたところ、最初の要素しかListモデルにマッピング出来ませんでした。

今回はその原因と実際に試してみた対処方法についてご紹介しようと思います。

手順

前提

以下のようなidを複数指定して返却するようなAPIがあったとします。

まずはModelにマッピングせずに直接取得する方法

まずはController側で直接配列のクエリパラメーターを受け取ってみましょう。

以下のようなroutesの記述とControllerがあったとします。

確認

この場合idsの値は、http://localhost:9000/v1/accounts?ids=1&ids=4&ids=6の場合はids146http://localhost:9000/v1/accounts?ids=1の場合は1http://localhost:9000/v1/accountsの場合はidsempty(nullではない)となります。

しっかりマッピング出来てますね♪

Formモデルで取得

しかし、routesControllerの引数に直接追加すると、クエリパラメーターが増えたりした際の修正範囲が増えてしまいます。

PlayFrameworkのFormはPOSTなどのリクエストボディのマッピングで主に使うようですがGETのクエリパラメーターに対してもモデルにマッピングし、さらにBeanバリデーションを活用したいので試してみましょう。

以下の検索モデルを用意します。

今回はとりあえずなにかしらのBeanバリデーションをかけたいので、@Sizeを利用し要素が4件以上指定された場合にバリデーションエラーを発生させるようにしてみます。

routesControllerは以下のように修正します。

確認

では、実際にリクエストしてみましょう。

まず、http://localhost:9000/v1/accountsの場合はids=nullとなります。この場合はControllerの引数で直接取得する場合との差異が出てますね。

次にhttp://localhost:9000/v1/accounts?ids=1の場合。

こちらは正しくListの要素として4要素がマッピングされていますね。

最後に複数クエリパラメーターが指定されたhttp://localhost:9000/v1/accounts?ids=1&ids=4&ids=8&ids=10の場合です。

あら、一つ目の要素しかマッピングされていませんし、Beanバリデーターも機能していませんね。。。

試しにCriteriaモデルのidsの型をListから配列にしてもダメでした。orz

配列をマッピングしたい場合は[]を付けるのがplayのお作法

実は、PlayFrameworkでは配列パラメーターをマッピングしたい場合は[]を付けるのが基本となっているようです。

試しに、http://localhost:9000/v1/accounts?ids[]=1&ids[]=4&ids[]=8&ids[]=10でリクエストしてみましょう。

正しくids4要素マッピングされ、Beanバリデーションも実行されていますね!

とはいえ、[]を付けるのはちょっと気持ち悪い。。。

しかし、クエリパラメーターに[]を付けるのはちょっと一般的ではない気がするのと、呼び出し側も修正しないといけないのでちょっと採用したくない案ですよね。。。

そこで、クエリには[]をつけずにFormでバインドしてBeanバリデーションを実行する方法を以下のようにして実現してみました!(もっとスマートな方法があるかもしれません。orz)

配列を[]を使わずにFormモデルにbind&Beanバリデーションを実行する方法

routesの修正

まず、routesの設定として配列になりうる要素のみControllerの引数で取得出来るようにします。

この際に、Stringで定義しておくことがポイントです。

ControllerでFormにbindする部分を修正

次に、Controllerの引数で受け取った配列を利用して意図的にバインドする処理を追加します。

確認

では、http://localhost:9000/v1/accounts?ids=1&ids=4&ids=8&ids=10にアクセスして確認してみましょう。

これで一応期待通りの動きになりましたね!

本日のオススメ商品

終わりに

痒いところに手が届かない部分を自前でカスタマイズしてみました。

他にも良い対応策があると思いますが、同じようにモヤモヤしている方は参考にしてみていただければなと思います。

336×280




336×280




CATEGORIES & TAGS

IT, , , , , , , , ,

blogenist

Author: blogenist