AIによる要約
@RequestParamが増えすぎたControllerは、読みづらく、修正漏れも起きやすくなります。検索条件や入力項目がひとまとまりなら、Formクラスや検索条件クラスへまとめることを検討します。ただし、何でもまとめればよいわけではなく、関連する値だけをまとめるのが大事です。


検索画面や一覧画面を作っていると、Controllerの引数に@RequestParamがどんどん増えることがあります。
最初は2個だった条件が、名前、ステータス、日付範囲、担当者、ページ番号と増えていき、気づくとメソッドのシグネチャだけで画面が埋まります。
この記事のポイント
@RequestParamが多すぎるControllerは読みづらい- 関連する検索条件はFormやConditionクラスにまとめる
- 単発の値まで無理にクラス化する必要はない
- Controller、Service、Repositoryへ渡す値の形を揃える
@RequestParamが増える典型パターン
検索画面や一覧画面では、最初はキーワードだけだった条件が、ステータス、日付範囲、担当者、並び順、ページ番号と増えていきます。
@GetMapping("/orders")
public String list(@RequestParam(required = false) String keyword,
@RequestParam(required = false) String status,
@RequestParam(required = false) String fromDate,
@RequestParam(required = false) String toDate,
@RequestParam(required = false) String staffId,
@RequestParam(defaultValue = "1") int page,
Model model) {
model.addAttribute("orders",
orderService.search(keyword, status, fromDate, toDate, staffId, page));
return "orders/list";
}
このコードは動きますが、引数の数が増えるほど読みづらくなります。Service呼び出しの順番を間違えるリスクもあります。
関連する条件はクラスにまとめる
検索条件として関連している値なら、FormクラスやSearchConditionクラスにまとめます。
public class OrderSearchForm {
private String keyword;
private String status;
private String fromDate;
private String toDate;
private String staffId;
private int page = 1;
}
@GetMapping("/orders")
public String list(OrderSearchForm form, Model model) {
model.addAttribute("orders", orderService.search(form));
return "orders/list";
}
Controllerの引数がすっきりし、検索画面の入力項目もFormクラスを見れば分かります。
何でもまとめればよいわけではない
注意したいのは、無関係な値まで1つのクラスに押し込まないことです。検索条件、ページング条件、画面制御用のフラグなどが混ざりすぎると、逆に分かりにくくなります。
// 避けたい例
public class ScreenForm {
private String keyword;
private String status;
private String loginUserRole;
private boolean showAdminMenu;
private String csrfToken;
}
Formクラスは便利ですが、画面に関係するものを何でも入れる箱ではありません。検索条件なら検索条件、登録入力なら登録入力というまとまりを守ります。
Serviceへ渡す前に整える
Controllerで受けたFormを、そのままServiceに渡してよいかはプロジェクト方針によります。検索条件を正規化してから渡す形にすると、Service以降が扱いやすくなります。
@GetMapping("/orders")
public String list(OrderSearchForm form, Model model) {
OrderSearchCondition condition = form.toCondition();
model.addAttribute("orders", orderService.search(condition));
return "orders/list";
}
日付文字列をLocalDateに変換する、空文字をnullにする、といった処理をどこで行うかを決めておくと、検索処理が安定します。
レビューでは変更しやすさを見られる
// レビューコメント例 @RequestParamが多くなっているので、検索条件クラスにまとめたいです。 // レビューコメント例 Service呼び出しの引数順が分かりづらいです。 OrderSearchConditionにまとめると、条件追加時の修正漏れを減らせます。
引数が多いこと自体より、条件追加や修正のときに壊れやすいことが問題です。
単発なら@RequestParamでよい
逆に、1つか2つの値しかない処理まで無理にForm化する必要はありません。
@GetMapping("/users")
public String list(@RequestParam(required = false) String keyword, Model model) {
model.addAttribute("users", userService.search(keyword));
return "users/list";
}
大事なのは、機械的にクラス化することではなく、読みやすさと変更しやすさです。
レビュー前のセルフチェック
確認リスト
- Controllerの引数が5個以上になっていないか
- 関連する検索条件を1つのクラスにまとめられないか
- Service呼び出しで引数順ミスが起きそうではないか
- 無関係な値まで同じFormに入れていないか
この記事とあわせて読みたい
- Spring Bootの@RequestParamとFormクラスの違いは?使い分けを解説
- Spring Bootの検索条件でnull・空文字にハマる原因と対策
- Spring BootのControllerでやってはいけないこと
まとめ
@RequestParamが多すぎるControllerは、検索条件や入力項目をクラスにまとめるサインです。
ただし、何でもまとめればよいわけではありません。関連する値をひとまとまりにし、ControllerとServiceの引数を読みやすくすることを目的に整理しましょう。
