Spring BootでREST APIを作ると、リクエストに含まれる値(パラメータ)を受け取る場面が必ず出てきます。よく使われるのが @PathVariable と @RequestParam ですが、より複雑なデータを扱いたいときには @RequestBody も重要な選択肢になります。「何が違うの?」「どれを使えばいいの?」と迷う方も多いはず。この記事では、これら3つのアノテーションの役割と使い分けのコツを整理して解説します。
🔰 はじめに
Webアプリケーションでは、クライアントから送られた値をもとに処理を分岐させたり、データを取得したりするのが基本です。Spring Bootではその値を受け取る手段とてて、@PathVariable、@RequestParam、そして @RequestBody が使われます。
@PathVariable:URLの一部を値として受け取る@RequestParam:クエリ文字列の値を受け取る@RequestBody:リクエストボディのJSONなどをJavaオブジェクトとして受け取る

それぞれの特徴と使いどころを理解することで、より自然で意図の伝わるAPI設計ができるようになります。
@PathVariableとは?
@PathVariable は、URLのパス部分に埋め込まれた値を受け取るためのアノテーションです。RESTfulな設計と非常に相性が良く、リソース(データ)の識別に使われます。例えば、ユーザーの詳細を取得する場合に /users/{id} のようにURLに値を埋め込んでアクセスする形式がよく使われます。
使い方の例:
@GetMapping("/users/{id}")
public String getUser(@PathVariable String id) {
return "User ID: " + id;
} この場合、/users/123 にアクセスすると “User ID: 123” が返ってきます。
🛠️ オプションの指定
@PathVariable には以下のような属性を指定できます:
| 属性名 | 説明 | 使用例 |
|---|---|---|
value | パス変数名を明示的に指定する | @PathVariable("id") String userId |
required | パラメータが必須かどうか(デフォルト:true) | @PathVariable(required = false) |
value 属性は、メソッドの引数名とURLのプレースホルダが一致していない場合に使用します。また、required を false にすることで、省略可能なパスパラメータとして扱うことができますが、URL構造的に省略できるように設計されている必要があります。
💡 補足:プレースホルダとは?
/users/{id}の{id}のように、URL内で値が動的に変わる部分をプレースホルダ(またはパス変数)と呼びます。これが@PathVariableによって受け取られる値になります。
複数のパス変数を扱う例:
@GetMapping("/users/{userId}/posts/{postId}")
public String getUserPost(@PathVariable String userId, @PathVariable String postId) {
return "User: " + userId + ", Post: " + postId;
}向いているケース:
- リソースの識別(例:ID、コードなど)
- たとえばユーザーIDや記事IDなど、特定のエンティティを一意に識別する値を受け取る際に使用します。
- RESTfulなURL設計に沿う場合
- エンドポイントの意味をURLの構造で表現したいときに適しています。たとえば
/users/{id}のように、リソースの階層構造をURLで示すことができます。
- エンドポイントの意味をURLの構造で表現したいときに適しています。たとえば
💡 補足:RESTfulなURL設計とは? RESTアーキテクチャに則ったAPI設計では、URLはリソース(データ)を表すべきで、動詞ではなく名詞を使うのが一般的です。たとえば
/usersはユーザーの一覧、/users/{id}は特定のユーザーを表します。これにより、直感的で予測しやすいAPIが実現できます。
@RequestParamとは?
@RequestParam は、URLのクエリパラメータ(?key=value 形式)を受け取るためのアノテーションです。主に検索条件やオプションの指定、フォーム入力などで使用されます。
使い方の例:
@GetMapping("/search")
public String search(@RequestParam String keyword) {
return "Searching for: " + keyword;
} この場合、/search?keyword=spring にアクセスすると "Searching for: spring" が返ります。
オプションの指定:
@RequestParam では以下の属性を指定できます:
| 属性名 | 説明 | 使用例 |
|---|---|---|
value | クエリパラメータ名を明示的に指定 | @RequestParam("q") String keyword |
required | パラメータが必須かどうか(デフォルトはtrue) | @RequestParam(required = false) |
defaultValue | 値が指定されなかったときのデフォルト値 | @RequestParam(defaultValue = "all") String type |
向いているケース:
- 検索条件やフィルターなどの任意パラメータ
- ユーザーによって条件が変わるような場面に最適です。たとえば商品検索で「価格上限」や「カテゴリ」などを自由に指定したいときなどです。
- 複数の値を組み合わせて使いたい場合
- 複数のクエリパラメータを組み合わせることで、柔軟に条件を追加・変更できます。たとえば
?type=book&sort=priceのようにURLを拡張できます。
- 複数のクエリパラメータを組み合わせることで、柔軟に条件を追加・変更できます。たとえば
🔍 違いと使い分けのポイント
@PathVariable と @RequestParam は、どちらもリクエストから値を受け取るための手段ですが、使いどころには明確な違いがあります。
@PathVariableは、リソース(データ)の位置やIDのような一意の識別子を表す場合に適しています。URLに値が直接組み込まれるため、視認性が高くRESTfulな設計にも合致します。@RequestParamは、検索条件や並び順など、処理の条件を指定する補助的なパラメータを受け取りたいときに向いています。クエリパラメータ形式で柔軟に追加できるのが特長です。
これらを正しく使い分けることで、APIの意図が明確になり、クライアントにも使いやすい設計になります。以下の表とも参考にしてみてください。
| 比較項目 | @PathVariable | @RequestParam |
|---|---|---|
| 値の場所 | URLパス(/users/123) | クエリ文字列(?id=123) |
| 主な用途 | リソースの特定 | 検索条件、オプション指定 |
| REST設計との相性 | ◎ | ◯(補助的に使う) |
| 複数パラメータ | △(URLが長くなる) | ◎(クエリで柔軟に追加可能) |
✏️ 応用:両方を使うケース例
@PathVariable と @RequestParam は組み合わせて使うことができ、リソースの識別と追加条件の指定を同時に行うケースでよく利用されます。たとえば、特定のユーザーの記事を取得する API において、ユーザーIDでリソースを特定し、記事のカテゴリで絞り込むといった使い方です。
@GetMapping("/users/{id}/posts")
public String getUserPosts(
@PathVariable String id,
@RequestParam(required = false) String category
) {
return "User: " + id + ", Category: " + category;
} この例では、/users/123/posts のようにユーザーを @PathVariable で特定し、?category=tech のように @RequestParam で任意の絞り込み条件を追加しています。
@RequestBodyとは?
@RequestBody は、リクエストのボディ部分に含まれる JSON や XML などのデータを、Javaオブジェクトとして受け取るためのアノテーションです。主に POST や PUT リクエストなど、クライアントから複数の情報をまとめて受け取るケースで使われます。フォーム送信やAPI連携などで、オブジェクト形式のデータをサーバーに渡す際に便利です。
使い方の例:
以下のJSONをAPIで受け取ることを措定します。
{
"name": "Taro",
"age": 30
}この JSON を User クラスにマッピングして受け取るようにすると、以下のような実装になります:
@PostMapping("/users")
public String createUser(@RequestBody User user) {
return "User created: " + user.getName() + ", Age: " + user.getAge();
}User クラスの定義例:
public class User {
private String name;
private int 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; }
}このように、リクエストの中身をJavaオブジェクトとして受け取ることで、柔軟で構造化されたデータ処理が可能になります。
❗ 補足:getter/setterがないとどうなる?
@RequestBodyを使ってリクエストボディをJavaオブジェクトにマッピングする際、Jacksonなどのライブラリは getter/setter を通じて値を設定します。そのため、getter/setter を省略すると値がnullのままになってしまう場合があります。確実にデータを受け取るには、必ず getter/setter を用意しましょう。なお、Lombok を使用すれば
@Dataを付けるだけで自動生成が可能です。@Data public class User { private String name; private int age; // getterとsetterを自分で書かなくても自動生成してくれる }
⚠️ よくある質問・エラーとその対処法
❓ 値が null になる
原因:
- パラメータ名が一致していない
@RequestBody使用時に getter/setter が定義されていない- JSONの構造とJavaクラスが一致していない
対処法:
@RequestParam("paramName")のように明示的に名前を指定する- JavaBeanにgetter/setterを定義(またはLombok使用)
- JSONのキーとJavaクラスのフィールド名を一致させる
❓ 型変換エラー(Failed to convert value of type)
原因:
- リクエストパラメータが指定の型に変換できない(例:
intに文字列が来た)
対処法:
- 基本は
String型で受け取り、必要に応じて変換する - 変換が必要な場合は、Springの
@InitBinderや@ModelAttributeを利用する方法も
❓ HTTP 400 エラー(Bad Request)
原因:
- 必須のパラメータが不足している
- JSONの構造が不正
- 型不一致(配列なのに単一値を渡している など)
対処法:
@RequestParam(required = false)を指定して省略を許容するdefaultValueを指定してデフォルト処理にする- JSONを送信する際は、POST/PUTリクエストの
Content-Typeをapplication/jsonにする
❓ @RequestBody で値が受け取れない
原因:
Content-Typeがapplication/json以外- フィールドに
getter/setterがない - JSON構造が合っていない
対処法:
fetchやPostmanでContent-Type: application/jsonを設定- Javaクラスに
getter/setterを明示するか@Dataを使う - JSONが正しい構造になっているか検証ツールで確認
❓ 複数の同名パラメータを配列で受け取れない
例:
URLに ?tag=java&tag=spring&tag=boot のような形式で送信
対処法:
@GetMapping("/tags")
public String getTags(@RequestParam List<String> tag) {
return "Tags: " + tag;
}パラメータを List<String> などのコレクション型で受け取ると自動でマッピングされます。
❓ JSONが受け取れているか確認したい
対処法:
- デバッグで
@RequestBodyに渡されたオブジェクトを確認する - ログに出力する:
System.out.println(user);やlogger.info(user.toString());
まとめ
Spring BootでWebアプリケーションを作る際、リクエストパラメータの受け取り方を理解することは、柔軟で安全なAPIを設計するうえで不可欠です。@PathVariable はURLに埋め込まれた値、@RequestParam はクエリパラメータ、@RequestBody はリクエストボディ全体をオブジェクトとして受け取る用途に使います。これらを正しく使い分けることで、意図が明確で読みやすいコードを実現できます。
次回は、ロジックの責務を整理するための Service クラスの導入について解説します。お楽しみに!






