LoginSignup
0
0

【Spring Boot】REST APIでpatchForObject(PATCH)使用時の注意点【RestTemplate】

Posted at

はじめに

APIについて学習中です。
前回REST API作成についてと、その利用について記事を書きました。
【Spring Boot + MyBatis】はじめてREST APIを作成してみる
【Spring Boot】作成したREST APIを使いたい【RestTemplate】

更新処理をPATCHで実装した際にうまくいかないことがあったので、今回記事にまとめます。

PUTとPATCHの違い

設計は参考そのままPUTにしていたのですが、実装時に設計を確認するのを失念しており、以下の記事を見てPATCHが適切なのではないかと考えました。

POST, PUT, PATCHの違い

PUT

  • 既存リソースの新しいものに置き換える
  • 新しいリソースの中に、既存リソースにある要素がない場合、その要素は削除される

PATCH

  • 既存リソースに新しいものを付け足す
  • 新しいリソースの中に、既存リソースにある要素がない場合でもその要素は削除されない

RestTemplateのpatchForObjectメソッド

取得処理(GET)はgetForObject、登録処理(POST)はpostForObjectを使ったので、更新処理はpatchForObjectを使用することにしました。

patchForObjectメソッド

  • 第一引数:送信先のURL
  • 第二引数:リクエスト情報(ヘッダーやボディ等)
  • 第三引数:レスポンスボディの型
  • 第四引数:URLのパラメータ

以下記事を見て、そのままでは使えないことを確認しました。

しかし、この通りやってもできませんでした。

エラーメッセージから推測できたのですが、Spring Framework 6.0よりApache HttpClient5になっていました。
画面側プロジェクトのpom.xmlに以下が必要になります。

pom.xml
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>

画面側プロジェクト

ManualsController.java
// マニュアルAPI URL(パラメータあり)
private static final String API_URL_PARAM = "http://localhost:8081/manual-api/{id}";

// 更新処理
@Transactional
@PostMapping("/manual/update")
public String update(int manualId,
                     @ModelAttribute @Validated ManualsForm manualsForm,
                     BindingResult result,
                     Model model) {
    // 入力エラーチェック
    if (result.hasErrors()) {
        return edit(manualId, manualsForm, model);
    }

    // FormをEntityにセットする処理は省略
    Manuals manual = setEntity(manualsForm);
    // マニュアルID
    manual.setManualId(manualId);
    
    // ★更新
    Manuals manualInfo = restTemplate.patchForObject(API_URL_PARAM, manual, Manuals.class, manualId);

    return "redirect:/manual/list";
}

API側プロジェクト

ManualsController.java
@PatchMapping("/manual-api/{manualId}")
public ResponseEntity<Manuals> update(@PathVariable int manualId, @RequestBody Manuals manual) {
    // 更新
    manualsMapper.update(manual);
    return ResponseEntity.ok(manual);
}

さいごに

結果として当初の設計通りPUTに修正しましたが、PATCHでも実装でき勉強になりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0