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クラスに任せましょう。コントローラーは「振り分け担当」として軽くしておくのが鉄則です。


今後の学習の指針

コントローラーの分割を学んだあとは、以下の内容を順に理解していくのがおすすめです。

  1. Service層とRepository層の分離
  2. DTO(Data Transfer Object)の使い方
  3. バリデーションの仕組み(@Validの使い方)
  4. 例外処理の統一(@ControllerAdviceなど)
  5. テストの書き方(MockMvcやRestAssuredの活用)

一歩一歩、実務に活かせる知識を身につけていきましょう!


他にも「こんな設計どうしたらいいの?」という疑問があれば、ぜひ聞いてくださいね!

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。