@RestControllerと@Controllerの違いを完全ガイド!Spring初心者でもわかるコントローラの使い分け
新人
「SpringでWebアプリを作ってるんですけど、@RestControllerと@Controllerってどう違うんですか?」
先輩
「それはSpring MVCにおける重要な違いだね。@RestControllerは主にAPI開発、@ControllerはHTML画面を返すときに使うよ。」
新人
「自分は画面も作る予定なんですけど、どっちを使えばいいんでしょうか?」
先輩
「画面(ビュー)を返すなら@Controllerだね。詳しく説明するよ!」
1. @RestControllerと@Controllerとは?
Spring Frameworkでは、リクエストを受け取るために「コントローラ(Controller)」という仕組みを使います。その中でも、よく使われるアノテーションが@Controllerと@RestControllerです。
@Controllerは、ユーザーにHTMLの画面を表示させたいときに使用します。主にWebページを返す処理で使います。
一方、@RestControllerは、JSONやXMLといったデータを直接返したいとき、つまりREST APIを作るときに使います。
この2つは見た目は似ていますが、動作がまったく違います。
具体的には、@RestControllerは、@Controllerに@ResponseBodyを付けたものと同じです。つまり、戻り値がそのままHTTPレスポンスとしてクライアントに返される仕組みです。
それぞれのコード例を見てみましょう。
■ @Controllerの例(HTMLを返す)
@Controller
public class HelloController {
@GetMapping("/hello")
public String helloPage(Model model) {
model.addAttribute("message", "こんにちは、Springの世界へようこそ!");
return "hello";
}
}
■ @RestControllerの例(JSONを返す)
@RestController
public class HelloRestController {
@GetMapping("/api/hello")
public String helloApi() {
return "こんにちは、APIの世界へようこそ!";
}
}
このように、@Controllerはテンプレートエンジン(Thymeleafなど)と組み合わせてHTMLを返し、@RestControllerはJSONなどのデータをそのまま返す違いがあります。
2. 用途の違いと使い分け
では、実際にどういう場面で@Controllerと@RestControllerを使い分けるのでしょうか?
以下のような基準で判断できます。
- 画面を表示するWebアプリを作るなら → @Controller
- スマホアプリやJavaScriptと通信するAPIを作るなら → @RestController
Spring BootではThymeleafなどのテンプレートエンジンと一緒に使うときに@Controllerが活躍します。
今回の記事では、HTML画面の表示を目的としたアプリケーションを前提としているので、@Controllerを使って開発を行います。
実際の画面遷移の例を見てみましょう。
■ コントローラとテンプレートの連携
@Controller
public class WelcomeController {
@GetMapping("/welcome")
public String welcome(Model model) {
model.addAttribute("user", "山田太郎");
return "welcome";
}
}
■ welcome.html(Thymeleafテンプレートの例)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ようこそ</title>
</head>
<body>
<h1>ようこそ、<span th:text="${user}">ゲスト</span>さん!</h1>
</body>
</html>
このように、@Controllerは画面をレンダリングする処理に適しており、ユーザーにわかりやすいUIを提供できます。
一方で、@RestControllerは機械同士の通信に強く、外部システムとの連携やモバイルアプリのバックエンドなどで利用されます。
ただし、今回の開発では画面がある前提なので、@RestControllerは使わず、@Controllerを中心に説明を進めていきます。
Springのコントローラ設計では、どちらを使うかがアプリケーションの性質によって決まるため、最初にしっかり理解しておくことが大切です。
3. @ControllerではどのようにViewが返されるのか
@Controllerを使用する場合、Javaのメソッドの戻り値には通常String型を指定します。そして、その戻り値は「テンプレート名」として解釈され、対応するHTMLファイルが呼び出されます。
このテンプレートファイルは、通常「resources/templates」フォルダ内に配置され、Thymeleafのようなテンプレートエンジンが内容を解析してHTMLとしてクライアントに返します。
たとえば、次のようなコードを書くと、Springはwelcome.htmlというテンプレートを探して画面表示を行います。
@Controller
public class PageController {
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("title", "トップページ");
return "home";
}
}
このreturn "home"の部分が重要です。ここではView名(テンプレートファイル名)を返しており、実際にはHTML形式でクライアントのブラウザにレンダリングされます。
テンプレートエンジンの一例として、Thymeleafを使うと下記のようなファイルを作成します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="${title}">ページタイトル</title>
</head>
<body>
<h1 th:text="${title}">タイトル</h1>
<p>このページはSpring MVCで作成されています。</p>
</body>
</html>
このように、HTMLテンプレートを通じてブラウザに画面が表示されるのが@Controllerの特徴です。
また、Spring MVCの内部では、ViewResolverという機能がテンプレート名と実際のファイルをマッピングしてくれるため、開発者はファイルパスを意識せずに直感的に開発できます。
4. @RestControllerではどうデータが返されるのか
@RestControllerを使うと、Javaのオブジェクトや文字列などが、Springの内部で自動的にJSONなどの形式に変換されてクライアントに返されます。
これは、Springが持つ「HTTPメッセージコンバータ」という仕組みによって実現されています。たとえば、Stringを返せばそのまま文字列がレスポンスとして送られ、Javaのオブジェクトを返せば自動的にJSONにシリアライズされます。
次のようなコードで確認できます。
@RestController
public class ApiController {
@GetMapping("/api/message")
public String getMessage() {
return "これはJSONレスポンスの例です。";
}
@GetMapping("/api/user")
public User getUser() {
return new User("taro", 25);
}
}
上記の例では、/api/messageにアクセスするとプレーンな文字列が返され、/api/userではUserオブジェクトがJSONに変換されて返されます。
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// GetterとSetterを必ず定義すること
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
ブラウザまたはPostmanなどでアクセスすると、次のようなJSONレスポンスが返ります。
{
"name": "taro",
"age": 25
}
このように、@RestControllerはHTMLテンプレートを使わず、直接JSONレスポンスを生成することで、フロントエンドや外部システムとの連携を高速化できます。
5. ソースコードでの具体的な違いを比較
ここでは@Controllerと@RestControllerの動作の違いを、具体的なコードで比較してみましょう。
それぞれのコントローラにおいて、同じURLパスに対して処理した場合の挙動を確認します。
■ @Controllerを使った例(テンプレートを返す)
@Controller
public class InfoController {
@GetMapping("/info")
public String info(Model model) {
model.addAttribute("message", "Springのコントローラは柔軟です");
return "info";
}
}
■ info.htmlのテンプレート
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>情報ページ</title>
</head>
<body>
<h2 th:text="${message}">メッセージが入ります</h2>
</body>
</html>
■ @RestControllerを使った例(JSONを返す)
@RestController
public class InfoRestController {
@GetMapping("/info")
public Map<String, String> info() {
Map<String, String> result = new HashMap<>();
result.put("message", "Springのコントローラは柔軟です");
return result;
}
}
このように、同じような処理でも@ControllerはHTMLテンプレートを通じてUIを提供し、@RestControllerは直接JSON形式でデータを返します。
今回のプロジェクトでは、画面を表示する要件のため、@Controllerを使用してテンプレートと連携する形でコントローラを構築します。
Spring MVCを使用する場合、画面ありの開発では@Controller、データAPIでの開発では@RestControllerというように、目的に応じて使い分けることが非常に重要です。
この違いを理解しておくと、今後のSpring開発において適切なアノテーションを選択できるようになります。
6. なぜ本記事では@Controllerを選ぶのか
今回のプロジェクトでは、ユーザーにHTMLの画面を表示させるWebアプリケーションを想定しています。そのため、データのみを返す@RestControllerではなく、@Controllerを選択しています。
たとえば、ログイン画面や登録フォーム、商品一覧ページなど、ユーザーが操作する画面をHTMLで構築したい場合には、テンプレートエンジンを使ってビューを返す必要があります。
@Controllerはそのような画面表示に特化しており、テンプレートファイルと連携して「見た目のあるページ」を作ることが可能です。
一方、@RestControllerはHTMLを扱わず、JSONレスポンスのみを返すため、ブラウザで直接画面を表示させる構成には向いていません。
さらに、初心者にとっても、テンプレートファイルとJavaのコントローラを組み合わせる@Controllerの構成は、目に見える成果(画面)があることで学習効果も高くなります。
実際に以下のようなコードを使えば、テンプレートファイルに値を渡して、画面上に表示できます。
@Controller
public class SampleController {
@GetMapping("/greeting")
public String greeting(Model model) {
model.addAttribute("message", "Springで画面を表示しています");
return "greeting";
}
}
このように、画面表示を主目的とする開発では、@Controllerを使うのが最適である理由がわかります。
7. よくある間違いや混乱しやすいポイントの解説
Spring初心者がつまずきやすいのが、@Controllerと@RestControllerの使い分けです。ここでは特によくある間違いをいくつか紹介します。
① @RestControllerで画面を返そうとする
初心者がよくやってしまうのが、@RestControllerを使ってHTMLテンプレートを返そうとすることです。しかし、@RestControllerはViewを探さず、文字列としてそのまま返してしまうため、期待する画面表示にはなりません。
例えば以下のようなコードを書くと、テンプレートが表示されると思ってしまうかもしれませんが、実際は文字列がそのまま表示されてしまいます。
@RestController
public class ErrorExampleController {
@GetMapping("/error")
public String errorPage() {
return "errorPage";
}
}
この場合、ブラウザには「errorPage」という文字列が表示されるだけで、HTML画面は表示されません。
② @Controllerを使ってJSONを返そうとして失敗する
逆に@Controllerを使ってJSONデータを返したいとき、@ResponseBodyアノテーションを付け忘れると、期待通りに動作しません。
@Controller
public class JsonExampleController {
@GetMapping("/json")
public String jsonData() {
return "{\"status\":\"ok\"}";
}
}
このように書いても、Springは「json」というテンプレートを探そうとしてエラーになります。
この場合、正しくは次のように@ResponseBodyを付ける必要があります。
@Controller
public class JsonExampleController {
@GetMapping("/json")
@ResponseBody
public String jsonData() {
return "{\"status\":\"ok\"}";
}
}
このような混乱を防ぐためにも、それぞれのアノテーションの動作を正確に理解して使い分けることが大切です。
8. @RestControllerと@Controllerの使い分けまとめ
最後に、Springで@RestControllerと@Controllerをどう使い分けるか、簡単な判断基準を整理しましょう。
- 画面(HTML)を表示したい場合 →
@Controller - データ(JSON)を返したい場合 →
@RestController - テンプレートエンジン(Thymeleafなど)を使いたい場合 →
@Controller - スマホアプリやJavaScriptとのAPI通信が目的 →
@RestController
今回のように、ユーザーに画面を提供するWebアプリケーションでは@Controllerが最適です。HTMLテンプレートと連携して、見た目のあるページを作ることができ、ユーザーの体験向上にもつながります。
一方、データだけを効率よく返す必要がある場合には@RestControllerを選ぶと、無駄のない設計が可能です。
初心者が混乱しやすいポイントではありますが、使い分けのコツさえつかめば、Springのコントローラ設計がより明確になります。
まずは@Controllerでの開発に慣れ、次に@RestControllerでのAPI設計にチャレンジしていくと、Springの理解が深まります。