Spring BootのController徹底解説|springboot controller入門
CONTENTS
- 1 ■controller の役割は「受付兼ディレクター」
- 2 ■ @Controller と @RestController の違い
- 3 ■controller にロジックを書くと破滅する理由
- 4 ■controller とRESTのURL設計
- 5 ■controller とDTOの関係
- 6 ■controller のあるあるアンチパターン
- 7 ■controller が上手い人の特徴
- 8 ■controller を綺麗に保つテクニック
- 9 ■controller は「技術の入り口」であり「設計の顔」
- 10 ■ 参考リンク:Spring Boot公式ドキュメント
- 11 ■ よくある質問(springboot controller)
- 12 ■ まとめ:springboot controller を制する者は、プロジェクトを制す
- 13 ■ 最後に:springbootのcontroller が楽しくなる瞬間が来る
Spring BootでWebアプリを作り始めると、必ず登場するのがController(コントローラー)です。
しかし、
- どこまで処理を書くべき?
- @Controller と @RestController の違いは?
- springboot controller の設計ってこれでいいの?
と悩む人は多いです。
本記事では、springboot controller の役割・設計・実務での正解を分かりやすく解説します。
■controller の役割は「受付兼ディレクター」
Spring BootのControllerは、簡単に言うと次のような役割を持ちます。
- 外部からデータを受け取る
- 適切な処理をServiceに委譲する
- レスポンスとして結果を返す
つまり、springboot controller は会社で言うフロントディレクターです。
ここで重要なのは、
controller はビジネスロジックを書く場所ではない
と理解することです。
■ @Controller と @RestController の違い
| アノテーション | 返すもの | 用途 |
|---|---|---|
| @Controller | HTML / View | MVC構成(テンプレートエンジンで画面を返す) |
| @RestController | JSON | API、SPA、モバイルアプリ向けのエンドポイント |
現代のWeb開発では、ほとんどが @RestController です。
理由は、
- SPA(React、Vue、Next.jsなど)との連携
- モバイルアプリ(Flutterなど)との通信
- 外部サービスとのAPI連携
といった事情があり、JSONを返すのが前提になっているからです。
■controller にロジックを書くと破滅する理由
初学者がやりがちなControllerの例を見てみます。
@PostMapping("/user")
public User createUser(User user) {
// validation
// DB insert
// transformation
return user;
}
一見シンプルで良さそうですが、実務ではこれは修正地獄の原因になります。
理由は、
- Validationが散らばる
- DBアクセスがControllerに直書きされる
- 変換処理が増えるとメソッドが肥大化する
正しい考え方は、
Controllerは薄く、ビジネスロジックはServiceに任せる
です。例として、springboot controller を次のように書き換えます。
@PostMapping("/users")
public User createUser(@RequestBody CreateUserRequest request) {
return userService.createUser(request);
}
このように、Controllerの責務は
- リクエストを受け取る
- Serviceに渡す
- レスポンスを返す
に限定するのが、springboot controller の基本設計です。
■controller とRESTのURL設計
次のようなURL設計を見たことはないでしょうか。
/saveUser
/getAllUser
/updateUser
/deleteUserById
このようなURLでもアプリは動きますが、REST設計としてはNGです。
RESTを意識した良いURL設計は次のようになります。
POST /users
GET /users
GET /users/{id}
PUT /users/{id}
DELETE /users/{id}
RESTの基本ルールは、
URLに動詞を入れず、リソース(名詞)で表現する
ことです。
こうすることで、
- 誰が見ても処理内容が予測しやすい
- HTTPメソッド(GET/POST/PUT/DELETE)と意味が直感的に対応する
- springboot controller の構造が自然に整理される
■controller とDTOの関係
ControllerでEntityを直接受け取ると、さまざまな問題が発生します。
- 画面要件やAPI仕様の変更でEntityが頻繁に書き換わる
- UI側の事情がドメイン層に侵食する
- 更新してはいけない項目まで上書きされるリスク
そのため、実務ではDTO(Data Transfer Object)を定義して、springboot controller ではDTOだけを扱うのが一般的です。
public class CreateUserRequest {
private String name;
private String email;
// getter / setter など
}
ControllerではこのDTOを受け取り、
- Validation
- Serviceへの引き渡し
までを担当し、Entityへの変換はService層で行うのが、springboot controller のベストプラクティスです。
■controller のあるあるアンチパターン
✕ Controllerが太りすぎる
「全部のロジックが詰まっているController」は、メソッド数もコード量も増え、修正のたびに全体を読み直す必要が出てきます。
✕ URLが動詞だらけ
「/createUser」「/getUser」など、動詞が並んだURLはREST的には非推奨です。長期運用を考えると、springboot controller の読みやすさ・拡張性に悪影響を与えます。
✕ エラーハンドリングがない
例外が発生するたびに500エラーを返していると、ログも追いづらく、現場の開発・運用チームが疲弊します。
✕ 戻り値が Map<String, Object> だらけ
「何でも入るから便利」と思いがちですが、型安全性が失われ、IDEの支援も弱まり、保守性が大きく落ちます。
■controller が上手い人の特徴
springbootのcontroller の設計が上手い人には、次のような特徴があります。
- Controllerは極限まで薄く保たれている
- URL設計がRESTのルールに沿っている
- DTOを適切に使い分けている
- エラーハンドリングが自然に統一されている
- Swagger/OpenAPIでAPI仕様が可視化されている
- 認証・認可ロジックがControllerに漏れ出していない
一言でまとめると、
springboot controller =「仕事を振る天才」
という設計ができている状態です。
■controller を綺麗に保つテクニック
● ValidationをServiceに押し込まない
リクエストの形式的なチェック(必須項目、形式エラーなど)は、Controller層(またはBean Validation)で早めに弾きます。これにより、Serviceは「正しい値が来る前提」で実装でき、責務が分離されます。
● 単一責任原則(SRP)を意識する
1メソッド=1機能を意識し、あまりに多くのことをしないようにします。処理が増えてきたら、springboot controller の役割を見直すサインです。
● メソッドの引数が多くなりすぎたらDTO化を検討
引数が3つ以上になってきたら、「リクエストDTOにまとめられないか?」を検討します。コードの見通しとAPIの明確さが向上します。
● 返すデータは明示的な型で
「とりあえずMapで返す」癖は卒業し、専用のレスポンスDTOを定義することで、springboot controller の可読性・保守性を高めましょう。
■controller は「技術の入り口」であり「設計の顔」
Controllerを書いていると、次のような問いに何度も向き合うことになります。
- どこにロジックを書くべきか
- 何をどこまで公開するか
- 誰が変換処理(DTO⇔Entity)を担うか
つまり、springboot controller は、
ソフトウェア設計そのものの理解が問われる層
とも言えます。Controllerのコードを見れば、そのプロジェクトの設計思想がほぼ丸見えです。
■ 参考リンク:Spring Boot公式ドキュメント
Spring Bootのより詳しい仕様や最新情報は、公式ドキュメントが最も信頼できます。
https://spring.io/projects/spring-boot
■ よくある質問(springboot controller)
Q1. Spring BootのControllerはどこまで責任を持つべき?
A. リクエストの受取、バリデーション、Service呼び出し、レスポンス生成までです。ビジネスロジックは基本的にService層に委譲し、springboot controller は「受付兼ディレクター」として振る舞うのが理想です。
Q2. @Controller と @RestController の使い分けは?
A. HTMLなどの画面(テンプレート)を返したい場合は @Controller、JSONを返すAPIを作りたい場合は @RestController を使います。Web API開発では、ほとんどのspringboot controller が後者になります。
Q3. Controllerに共通処理を書くのはあり?
A. ログ出力や認証などの共通処理は、Filter、Interceptor、ControllerAdviceなどに切り出した方が保守性が高いです。springboot controller には「ルートごとの役割」に集中させるのがおすすめです。
Q4. Controllerが肥大化した場合どうする?
A. DTO導入、Serviceの分割、エラーハンドリングの共通化(ExceptionHandler)を行うことでスリム化できます。また、URL設計と責務分担を見直すことで、springboot controller の見通しが一気に良くなります。
■ まとめ:springboot controller を制する者は、プロジェクトを制す
Spring Bootは便利で、Controllerも簡単に書けます。しかし、簡単に書けてしまうからこそ、設計の差がはっきりと出ます。
controller をうまく設計するためのポイントは次の通りです。
- RESTを意識したURL設計を行う
- Controllerは薄く保ち、Serviceにロジックを寄せる
- DTOとEntityを分けて扱う
- 責務分担とエラーハンドリングを意識する
これだけで、現場では「できる人」扱いされるレベルのspringboot controller が書けるようになります。
■ 最後に:springbootのcontroller が楽しくなる瞬間が来る

最初のうちは、springbootのcontroller の設計に悩むことも多いはずです。しかし、設計やアーキテクチャの考え方が身についてくると、次第にControllerを書くのが楽しくなります。
その先には、
- 美しい設計
- 高い保守性
- チームメンバーの幸福
- 自分自身の市場価値の向上
が待っています。
そして、もし 「もっと体系的に学びたい」「実務レベルの設計力を身につけたい」 と感じた方は、次のステップとして zerocode を活用することをおすすめします。
開発現場で必要とされる技術や設計思考を、短期間で効率よく学べるオンライン学習サービスです。
Spring Boot、API設計、アーキテクチャなど、実務でそのまま使える知識が身につきます。
学習の次のステージへ進みたい方はこちら:ZeroCode