はじめに
APIについて学習中です。
前回REST API作成についてと、その利用について記事を書きました。
【Spring Boot + MyBatis】はじめてREST APIを作成してみる
【Spring Boot】作成したREST APIを使いたい【RestTemplate】
更新処理をPATCHで実装した際にうまくいかないことがあったので、今回記事にまとめます。
PUTとPATCHの違い
設計は参考そのままPUTにしていたのですが、実装時に設計を確認するのを失念しており、以下の記事を見てPATCHが適切なのではないかと考えました。
PUT
- 既存リソースの新しいものに置き換える
- 新しいリソースの中に、既存リソースにある要素がない場合、その要素は削除される
PATCH
- 既存リソースに新しいものを付け足す
- 新しいリソースの中に、既存リソースにある要素がない場合でもその要素は削除されない
RestTemplateのpatchForObjectメソッド
取得処理(GET)はgetForObject、登録処理(POST)はpostForObjectを使ったので、更新処理はpatchForObjectを使用することにしました。
patchForObjectメソッド
- 第一引数:送信先のURL
- 第二引数:リクエスト情報(ヘッダーやボディ等)
- 第三引数:レスポンスボディの型
- 第四引数:URLのパラメータ
以下記事を見て、そのままでは使えないことを確認しました。
- RestTemplateに追加されたpatchForObjectはデフォ実装(HttpURLConnection使うやつ)だと実質使えません
- SpringBoot RestTemplateでPATCHを使う場合の注意メモ
しかし、この通りやってもできませんでした。
エラーメッセージから推測できたのですが、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でも実装でき勉強になりました。