WebAPIの基本はここから!@PathVariable・@RequestParam・@RequestBodyの使い方講座【Spring Boot】

  • LINEで送る
WebAPIの基本はここから@PathVariable@RequestParam@RequestBodyの使い方講座

 Spring BootでREST APIを作ると、リクエストに含まれる値(パラメータ)を受け取る場面が必ず出てきます。よく使われるのが @PathVariable@RequestParam ですが、より複雑なデータを扱いたいときには @RequestBody も重要な選択肢になります。「何が違うの?」「どれを使えばいいの?」と迷う方も多いはず。この記事では、これら3つのアノテーションの役割と使い分けのコツを整理して解説します。

🔰 はじめに

 Webアプリケーションでは、クライアントから送られた値をもとに処理を分岐させたり、データを取得したりするのが基本です。Spring Bootではその値を受け取る手段とてて、@PathVariable@RequestParam、そして @RequestBody が使われます。

  • @PathVariableURLの一部を値として受け取る
  • @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のプレースホルダが一致していない場合に使用します。また、requiredfalse にすることで、省略可能なパスパラメータとして扱うことができますが、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で示すことができます。

💡 補足: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オブジェクトとして受け取るためのアノテーションです。主に POSTPUT リクエストなど、クライアントから複数の情報をまとめて受け取るケースで使われます。フォーム送信や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-Typeapplication/json にする

@RequestBody で値が受け取れない

原因:

  • Content-Typeapplication/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 クラスの導入について解説します。お楽しみに!

最新の投稿

SNSでもご購読できます。

コメントを残す