Spring Bootのコントローラーはどう分割する?新人エンジニア向けにわかりやすく解説!
こんにちは。ゆうせいです。
今回は、Spring Bootの「コントローラー」クラスをどのように分割すべきか、というテーマでお話しします。
「1つのコントローラーに全部書いちゃってるけど、これでいいの?」
「Controllerの設計って、正解があるの?」
…そんな悩み、ありますよね。
大丈夫です。この記事では、コントローラーの役割から分割の考え方、設計パターンまで、図や例を使って初心者にもわかりやすく解説していきます!
コントローラーとは何か?まずは役割をおさらい!
コントローラーの本来の役割
Spring Bootにおける「コントローラー(Controller)」は、ユーザーからのリクエスト(HTTPリクエスト)を受け取り、それに対するレスポンス(HTTPレスポンス)を返すためのクラスです。
たとえるなら、「受付係」のような存在です。
- お客様(ユーザー)が「〇〇がしたい」と言ってくる
- 受付係(コントローラー)がそれを聞いて、担当部署(サービスやリポジトリ)に取り次ぐ
- 最後に結果を持ってお客様に返す
このような流れですね。
分割しないとどうなる?
一つのクラスに詰め込みすぎると…
例えば、以下のようにユーザー管理、商品管理、注文管理など、複数の処理を1つのコントローラークラスに書いてしまうとどうなるでしょうか?
@RestController
public class MainController {
@GetMapping("/users")
public List<User> getUsers() {...}
@PostMapping("/products")
public Product addProduct(...) {...}
@PutMapping("/orders/{id}")
public Order updateOrder(...) {...}
}
このような設計では、次のような問題が出てきます。
問題点 | 説明 |
---|---|
可読性が低い | どこに何が書いてあるか分かりにくい |
修正が怖い | 関係ない処理に影響を与えるかも…という恐怖 |
テストしにくい | 単体テストの範囲が広すぎて複雑になる |
コントローラーの適切な分割方法
分割の基本単位は「機能単位」
もっとも基本的な分け方は、「機能単位」で分けることです。
UserController
(ユーザーに関する処理を担当)ProductController
(商品に関する処理を担当)OrderController
(注文に関する処理を担当)
というように、ドメインごと(機能ごと)に分けるのが基本です。
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public List<User> listUsers() {...}
}
@RestController
@RequestMapping("/products")
public class ProductController {
@PostMapping
public Product createProduct(...) {...}
}
さらに細かくしたいときは?
大きなシステムでは、「ユーザー管理」だけでも以下のように細分化される場合があります。
- 一覧取得
- ログイン処理
- パスワード再発行
- アカウント停止 など
こういった場合は、APIの役割ごとに分割するのもアリです。
例:ユーザー関連のコントローラーを分けるパターン
UserQueryController
(情報の取得専用)UserCommandController
(新規作成・更新・削除など)
このようにCQRS(Command Query Responsibility Segregation)という設計思想に沿って分けるのも、実はよくある方法です。
分割の判断基準は?
判断に迷ったら、以下の視点でチェック!
判断基準 | チェックポイント |
---|---|
責務 | 「このクラス、やってること多すぎない?」 |
命名 | クラス名が「何をしているのか」明確か |
大きさ | クラスのコード量が多すぎないか(200行以上なら要注意) |
URL構成 | /api/users /api/products など、URL単位で整理されているか |
分割のメリットとデメリット
メリット
- 読みやすい:どこに何があるか明確
- テストしやすい:関心ごとが明確だから
- 修正しやすい:影響範囲が限定的
デメリット
- クラスが増える:初心者には管理が大変に感じるかも
- 設計力が求められる:どの粒度で分けるか判断が必要
でも、慣れれば必ず分割した方がラクになります!
よくある質問
Q1:コントローラーの数はいくつが適切?
A:プロジェクトの規模によりますが、10以上あっても全く問題ありません。それぞれが独立した役割を持っていれば、むしろ増えた方が整理されていて良い設計です。
Q2:コントローラーでロジックを書いてもいいの?
A:基本的にはダメです。ビジネスロジック(処理の本体)はServiceクラスに任せましょう。コントローラーは「振り分け担当」として軽くしておくのが鉄則です。
今後の学習の指針
コントローラーの分割を学んだあとは、以下の内容を順に理解していくのがおすすめです。
- Service層とRepository層の分離
- DTO(Data Transfer Object)の使い方
- バリデーションの仕組み(@Validの使い方)
- 例外処理の統一(@ControllerAdviceなど)
- テストの書き方(MockMvcやRestAssuredの活用)
一歩一歩、実務に活かせる知識を身につけていきましょう!
他にも「こんな設計どうしたらいいの?」という疑問があれば、ぜひ聞いてくださいね!
セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク
投稿者プロフィール
