@PutMappingの使い方と引数を徹底解説!【初心者向け】

はじめに

こんにちは! 今回は、Spring Frameworkの中でもよく使われる@PutMappingというアノテーションについて解説します。
このアノテーションを使えば、Webアプリケーションでのデータ更新処理が簡単に実現できます!

@PutMappingって何?

@PutMappingとは

「既に存在するデータを更新するために使アノテーション」

のことです。

たとえば、ユーザーのプロフィール情報や商品の在庫情報を変更したいとしましょう。
そういう時はこのアノテーションを使うことで、受け取ったPUTリクエスト(更新情報)に基づいてサーバー側でデータを更新する処理を簡単に行うことができます。

PUTリクエストはブラウザのURLバーから直接送信することはできませんが、APIクライアントツール(たとえばPostman)や、JavaScriptのfetch APIを使って送信できます。@PutMappingを使うことで、こうした更新リクエストに対する処理をスムーズに実装できるようになります。

基本的な使い方

とりあえず使ってみたほうが早いです!以下のコードは、ユーザー情報を更新するケースです。
情報を投げる側と受け取る側がいるので、両方書きますね。

↓受け取る側

@PutMapping("/users")
public User updateUser(@RequestBody User updatedUser) {
    // ユーザー情報を更新
    userDatabase.update(updatedUser.getId(), updatedUser); // 仮のデータベースでの更新
    return updatedUser; // 更新したユーザーを返す
}

このコードでは、localhost:8080/usersというURLに対するPUTリクエストを受け取り、そのユーザーIDに対応するユーザー情報を更新します。
@RequestBody:投げられたデータをUserオブジェクトとして受け取ることができます。

↓投げる側

const updatedUser = {
    id: 1, // 更新したいユーザーのID
    name: "山田太郎更新",
    email: "taro-updated@example.com"
};

fetch(`http://localhost:8080/users`, {
    method: 'PUT',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(updatedUser)
});

投げる側はfetchを使ってPUTリクエストを送信し、更新したユーザーのデータをサーバーから受け取って表示します。

@PutMappingの使い方【応用編】

ここからは、@PutMappingのもう少し高度な使い方を紹介します。これらの例をマスターすれば、複雑な更新処理も簡単に実装できるようになります!

1. URLパス内の変数を使う

@PutMappingでは、URLのパスに動的な値(パス変数)を組み込むことができます。たとえば、特定の商品の在庫情報を更新する場合を考えてみましょう。

@PutMapping("/products/{id}/stock")
public ResponseEntity<Product> updateProductStock(@PathVariable("id") Long productId, @RequestBody int newStock) {
    Product product = productService.updateStock(productId, newStock);
    return ResponseEntity.ok(product);
}

この例では、/products/{id}/stockに対してPUTリクエストが送信されたときに、URLに含まれる商品ID(id)とリクエストボディに含まれる新しい在庫数(newStock)を使って、在庫情報を更新しています。

2. バリデーションの追加

データを更新するときは、入力値のバリデーションが必要になる場合があります。@PutMappingと一緒に@Validアノテーションを使うことで、リクエストボディのバリデーションを簡単に行えます。

@PutMapping("/users/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody UserDto userDto, BindingResult result) {
    if (result.hasErrors()) {
        return ResponseEntity.badRequest().build();
    }
    User user = userService.updateUser(id, userDto);
    return ResponseEntity.ok(user);
}

このコードでは、ユーザー情報の更新時に@Validを使ってDTOのフィールドをバリデートし、エラーがある場合は400 Bad Requestを返します。
※DTO(Data Transfer Object):データを一時的に保持し、異なる層間でデータを転送するためのオブジェクト。

3. クエリパラメータを使った更新処理

クエリパラメータを使用して、PUTリクエストをさらに細かく制御することができます。

@PutMapping("/products/{id}")
public ResponseEntity<Product> updateProductPrice(@PathVariable("id") Long productId, 
                                                 @RequestParam(value = "price") double newPrice) {
    Product product = productService.updatePrice(productId, newPrice);
    return ResponseEntity.ok(product);
}

この例では、/products/{id}?price=99.99のようなリクエストに対して商品価格を更新します。

4. JSON形式のレスポンスを返す

API開発では、PUTリクエストの応答としてJSON形式のデータを返すことが一般的です。@ResponseBodyを付けることで、直接JSONデータを返すことができます。

@PutMapping("/api/products/{id}")
@ResponseBody
public Product updateProductDetails(@PathVariable Long id, @RequestBody Product updatedProduct) {
    return productService.updateProduct(id, updatedProduct);
}

この方法で、APIクライアントやJavaScriptのフロントエンドは、更新された商品のデータをJSONとして受け取ることができます。

5. ヘッダー情報を使った更新

特定の条件に基づいてリクエストを処理する場合、リクエストヘッダーを使って情報を取得することができます。

@PutMapping("/products/{id}")
public ResponseEntity<Product> updateProductWithHeader(@PathVariable Long id, 
                                                       @RequestBody Product updatedProduct, 
                                                       @RequestHeader("Authorization") String authToken) {
    if (!authService.isValidToken(authToken)) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
    }
    Product product = productService.updateProduct(id, updatedProduct);
    return ResponseEntity.ok(product);
}

ここでは、リクエストヘッダーから認証トークンを取得し、認証が成功した場合にのみ商品データを更新しています。

@PutMappingの引数

@PutMappingでは、さまざまな引数を指定してリクエストの処理を細かく制御することができます。

1. value属性

@PutMappingvalue属性を使って、どのURLパスに対してこのメソッドが応答するのかを指定します。

@PutMapping(value = "/users/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
    return ResponseEntity.ok(userService.updateUser(id, user));
}

この例では、/users/{id}へのPUTリクエストを処理します。
省略しないで書くとこうなるということです。

2. consumes属性

consumes属性を使うことで、リクエストが特定のメディアタイプを含んでいる場合のみメソッドを実行できます。

@PutMapping(value = "/users/{id}", consumes = "application/json")
public ResponseEntity<User> updateUserJson(@PathVariable Long id, @RequestBody User user) {
    return ResponseEntity.ok(userService.updateUser(id, user));
}

このコードでは、リクエストがapplication/jsonである場合にのみ処理が実行されます。

3. produces属性

produces属性を使うことで、レスポンスのメディアタイプを指定できます。

@PutMapping(value = "/api/users/{id}", produces = "application/json")
public @ResponseBody User updateUserAndReturnJson(@PathVariable Long id, @RequestBody User user) {
    return userService.updateUser(id, user);
}

この例では、JSON形式でデータを返します。

おわりに

@PutMappingは、データの更新処理を簡単に行える便利なアノテーションです。特にREST APIの開発においては欠かせない存在です。今回は基本的な使い方から応用的な例まで幅広く紹介しましたので、ぜひ実際にコードを書いて試してみてください!

もっと詳しく知りたい方は、Spring公式ドキュメントを見てみてくださいね。

他のMappingについて知りたい方はこちらをどうぞ!↓↓

タイトルとURLをコピーしました