AIによる要約
@RequestBodyは、HTTPリクエストのボディに入っているJSONをJavaオブジェクトへ変換して受け取るために使います。クエリ文字列やHTMLフォームを受けるためのものではありません。APIの入口ではRequest DTOとセットで考えると安全です。


Spring BootでAPIを作ると、@RequestBodyがよく出てきます。
画面フォーム中心の開発から入った人は、@RequestParamやFormクラスとの違いが分からず、JSONがnullになる、400エラーになる、といった問題にぶつかりやすいです。
この記事のポイント
@RequestBodyはJSONなどのリクエストボディを受け取る- HTMLフォームやクエリ文字列とは受け取り方が違う
- APIではRequest DTOを用意してEntityと分ける
- Content-TypeやJSONの項目名ずれに注意する
@RequestBodyはリクエストボディを読む
@RequestBodyは、HTTPリクエストのボディに入っているデータをJavaオブジェクトへ変換します。Spring BootのAPIでは、JSONを受け取るときによく使います。
@PostMapping("/api/users")
public ResponseEntity<Void> create(@RequestBody UserCreateRequest request) {
userService.create(request);
return ResponseEntity.ok().build();
}
このControllerは、リクエストボディのJSONをUserCreateRequestへ変換して受け取ります。
送信されるJSONの例
POST /api/users
Content-Type: application/json
{
"name": "田中",
"email": "tanaka@example.com"
}
このJSONのnameとemailが、Request DTOのフィールドへ対応します。項目名がずれると値が入りません。
public class UserCreateRequest {
private String name;
private String email;
// getter / setter
}
@RequestParamとの違い
@RequestParamは、主にクエリ文字列やフォームの単発パラメータを受け取ります。JSONボディを受け取るためのものではありません。
// クエリ文字列を受ける
@GetMapping("/api/users")
public List<UserResponse> search(@RequestParam String keyword) {
return userService.search(keyword);
}
// JSONボディを受ける
@PostMapping("/api/users")
public ResponseEntity<Void> create(@RequestBody UserCreateRequest request) {
userService.create(request);
return ResponseEntity.ok().build();
}
URLの後ろに付く値なのか、本文として送られるJSONなのかで使い分けます。
入力チェックは@Validと組み合わせる
APIでも入力チェックは必要です。Request DTOに制約を付け、Controllerで@Validを付けます。
public class UserCreateRequest {
@NotBlank
private String name;
@NotBlank
@Email
private String email;
}
@PostMapping("/api/users")
public ResponseEntity<Void> create(@RequestBody @Valid UserCreateRequest request) {
userService.create(request);
return ResponseEntity.ok().build();
}
画面フォームと違い、APIではエラー時に画面へ戻すのではなく、400レスポンスとしてエラー内容を返す設計が多いです。
Entityを直接受け取らない
APIでも、Entityを@RequestBodyで直接受けるのは避けた方がよいことが多いです。
// 避けたい例
@PostMapping("/api/users")
public ResponseEntity<Void> create(@RequestBody User user) {
userRepository.save(user);
return ResponseEntity.ok().build();
}
DBの構造や更新させたくない項目がAPIに漏れる可能性があります。Request DTOを作り、Serviceで必要な形へ変換しましょう。
400エラーになったときの確認ポイント
確認リスト
Content-Type: application/jsonになっているか- JSONの項目名とRequest DTOのフィールド名が合っているか
- Request DTOにgetter/setterやコンストラクタが適切にあるか
- JSONの文法が壊れていないか
- 入力チェックで弾かれていないか
この記事とあわせて読みたい
- Spring Bootの入力値はどこで受ける?@RequestParam・@PathVariable・@RequestBodyの使い分け
- Spring Bootの入力チェックはどこでやる?ControllerとServiceの役割
- Spring BootのControllerでやってはいけないこと
まとめ
@RequestBodyは、JSONなどのリクエストボディをJavaオブジェクトとして受け取るためのアノテーションです。
クエリなら@RequestParam、URLの一部なら@PathVariable、JSONなら@RequestBody。この区別ができると、APIのControllerを読みやすくなります。
