Spring Bootの@GetMappingと@PostMappingの違いを解説する記事のアイキャッチ。Java道場風の空間で若手エンジニアがGETとPOSTの使い分けを学ぶイラスト。

Spring

Spring Bootの@GetMappingと@PostMappingの違い|@RequestMappingとの使い分け

AIによる要約

@GetMappingは一覧表示や詳細表示など、基本的にサーバーの状態を変更しない取得処理へ使います。@PostMappingは登録、申請、ファイル取込など、状態を変更する処理へ使います。@RequestMappingはController全体の共通パスや、HTTPメソッド以外の条件も含めて指定するときに使います。削除をGETで実装せず、成功後はredirectすることが現場で重要な確認点です。

新人SE
新人SE
画面が表示できれば、全部@GetMappingでも問題ないのでしょうか?
ポンコツSE
ポンコツSE
表示結果だけで決めません。そのリクエストがサーバーのデータを変更するか、再実行されても安全かでHTTPメソッドを選びます。

Spring BootのControllerでは、@GetMapping@PostMappingを頻繁に使います。書き方は似ていますが、単に「画面表示はGET、ボタンはPOST」と暗記すると、検索、削除、確認画面などで判断に迷います。

HTTPメソッドは、URLと合わせて処理の意味を表します。使い方を誤ると、ブラウザの再読み込みで二重登録されたり、リンクを開いただけでデータが削除されたりします。この記事では社員管理画面を例に、新人が実装レビューで説明できる基準を整理します。

この記事のポイント

  • GETは基本的に参照、POSTは登録や業務処理に使う
  • 同じURLでもHTTPメソッドが違えば別の処理として定義できる
  • Controller共通パスはクラスの@RequestMappingへまとめる
  • 登録成功後はredirectし、再読み込みによる二重送信を防ぐ

@GetMappingと@PostMappingの基本的な違い

観点@GetMapping@PostMapping
主な用途一覧、詳細、検索結果、入力画面登録、申請、実行、ファイル取込
データ変更原則として行わない行う処理に使う
パラメータクエリ文字列やパスに現れやすいFormやリクエストボディで送ることが多い
再読み込み同じ参照結果を得られる設計が基本二重実行へ注意が必要

GETは安全なメソッドとして、サーバーの状態を変えないことが期待されます。アクセスログや最終閲覧日時など技術的な情報が更新される場合はありますが、注文登録や削除のような利用者が意図する業務データを変更させません。

POSTは、同じリクエストを2回送ると2件登録される可能性があります。そのため、画面の二重送信防止、サーバー側の重複チェック、トークンなど、処理に応じた対策を考えます。

@GetMappingの実装例

一覧表示や詳細表示、登録画面の初期表示はGETが基本です。

@Controller
@RequestMapping("/employees")
public class EmployeeController {

    @GetMapping
    public String list(Model model) {
        model.addAttribute("employees", employeeService.findAll());
        return "employees/list";
    }

    @GetMapping("/{employeeId}")
    public String detail(
            @PathVariable long employeeId,
            Model model) {
        model.addAttribute("employee", employeeService.findById(employeeId));
        return "employees/detail";
    }

    @GetMapping("/new")
    public String showCreateForm(Model model) {
        model.addAttribute("employeeForm", new EmployeeForm());
        return "employees/form";
    }
}

クラスの@RequestMapping("/employees")と、各メソッドのパスを組み合わせます。たとえば詳細表示はGET /employees/123になります。

@PostMappingの実装例

登録や申請など、サーバーの状態を変更する処理をPOSTで受けます。

@PostMapping
public String create(
        @Valid @ModelAttribute("employeeForm") EmployeeForm form,
        BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "employees/form";
    }

    long employeeId = employeeService.create(form);
    return "redirect:/employees/" + employeeId;
}

入力エラーでは同じテンプレートを直接返し、登録成功後に詳細画面へredirectしています。登録後のURLをブラウザで再読み込みしても、GETの詳細表示が実行されるため、POSTが再送信されにくくなります。

@RequestMappingはいつ使うのか

@GetMapping@RequestMapping(method = RequestMethod.GET)を読みやすくした合成アノテーションです。POST、PUT、PATCH、DELETEにも対応する専用アノテーションがあります。

// 同じ意味だが、通常は@GetMappingの方が意図を読みやすい
@RequestMapping(path = "/employees", method = RequestMethod.GET)
public String list() {
    return "employees/list";
}

@GetMapping("/employees")
public String listReadable() {
    return "employees/list";
}

メソッド単位では@GetMappingなどを使い、Controller全体の共通パスをクラスの@RequestMappingへ置く形がよく使われます。また、consumesproduces、ヘッダー条件などをまとめて指定する場合も@RequestMappingが候補です。

@RestController
@RequestMapping(
        path = "/api/employees",
        produces = MediaType.APPLICATION_JSON_VALUE)
public class EmployeeApiController {
    // ...
}

同じURLをGETとPOSTで使ってもよい

URLだけでなく、HTTPメソッドも処理を識別する条件です。/employeesをGETで呼べば一覧取得、POSTで呼べば新規登録という設計にできます。

@GetMapping("/employees")
public List<EmployeeResponse> list() {
    return employeeService.findAll();
}

@PostMapping("/employees")
public ResponseEntity<EmployeeResponse> create(
        @Valid @RequestBody EmployeeCreateRequest request) {
    EmployeeResponse created = employeeService.create(request);
    return ResponseEntity.status(HttpStatus.CREATED).body(created);
}

HTML画面では/employees/newをGETの入力画面、/employeesをPOSTの登録先にする構成もよくあります。URL命名だけを真似せず、既存プロジェクトの規約に揃えます。

削除処理を@GetMappingにしてはいけない

// 避ける: URLを開いただけで削除される
@GetMapping("/{employeeId}/delete")
public String delete(@PathVariable long employeeId) {
    employeeService.delete(employeeId);
    return "redirect:/employees";
}

GETはリンクの先読み、クローラー、ブラウザ履歴など、人が削除ボタンを押す以外の理由でもアクセスされ得ます。GETでデータを変更すると、意図しない実行につながります。

HTML FormであればPOSTを使い、REST APIであれば@DeleteMappingを検討します。CSRF対策、権限確認、対象の存在確認もHTTPメソッドとは別に必要です。

@PostMapping("/{employeeId}/delete")
public String deleteFromScreen(@PathVariable long employeeId) {
    employeeService.delete(employeeId);
    return "redirect:/employees";
}

@DeleteMapping("/api/employees/{employeeId}")
public ResponseEntity<Void> deleteFromApi(@PathVariable long employeeId) {
    employeeService.delete(employeeId);
    return ResponseEntity.noContent().build();
}

PUT・PATCH・DELETEはどう使い分けるか

アノテーション主な意味
@PutMapping対象全体を置き換える更新社員情報全体の更新
@PatchMapping対象の一部を変更在籍ステータスだけ変更
@DeleteMapping対象を削除社員情報を削除

実際の業務システムでは、更新もPOSTへ統一する画面設計や、論理削除を使う設計があります。HTTPの一般原則を理解した上で、API仕様書と既存Controllerの方針を優先してください。

405 Method Not Allowedが出たときの確認点

URLは合っているのにHTTPメソッドがControllerの定義と一致しない場合、405エラーになることがあります。404と混同せず、次を確認します。

  • HTML FormのmethodがControllerと一致しているか
  • JavaScriptのfetchやAjaxで指定したmethodが正しいか
  • クラスとメソッドのパスを結合したURLが正しいか
  • 同じパスを別Controllerが重複定義していないか
  • PUTやDELETEをHTML Formから送るための構成が整っているか
<!-- Controllerが@PostMappingならmethod="post"を指定する -->
<form th:action="@{/employees}" method="post">
    <!-- 入力欄 -->
    <button type="submit">登録</button>
</form>

URLとメソッドを設計する手順

  1. 何を対象にする処理かを名詞で決める
  2. 参照か、登録・変更かを判断する
  3. GET、POST、PUT、PATCH、DELETEから意味に合うものを選ぶ
  4. 成功時、入力エラー時、対象不存在時の遷移を決める
  5. Controller、HTML、JavaScript、API仕様書のメソッドを揃える

アノテーションから考え始めず、「この操作は何を変えるのか」を先に文章にします。

現場レビューでよくある指摘

// レビューコメント例
削除処理がGETになっています。
リンクの先読みでも実行され得るため、POSTまたはDELETEへ変更してください。

// レビューコメント例
登録成功後もテンプレートを直接返しているため、再読み込みで再POSTされます。
登録完了後は詳細画面へredirectしてください。

// レビューコメント例
全メソッドで"/employees"が重複しています。
クラスの@RequestMappingへ共通パスをまとめると読みやすくなります。

提出前のセルフチェック

  • GETで業務データを登録・更新・削除していないか
  • 登録や申請はPOSTになっているか
  • 成功後にredirectし、二重送信を防いでいるか
  • ControllerとHTML FormのHTTPメソッドが一致しているか
  • 共通パスをクラスの@RequestMappingへまとめられるか
  • API仕様書とステータスコードの方針に合っているか

HTTPとWebアプリの基本を学ぶ参考書

Springのアノテーションだけでなく、HTTPメソッドやステータスコードの意味を押さえると、Controller設計の判断が安定します。Webの基本へ立ち戻りたいときに役立つ一冊です。

書籍「Webを支える技術」の表紙
商品画像:Amazon.co.jp
PR Web開発に入る新人向け

Webを支える技術

山本 陽平 (著)

HTTP・URI・RESTを、Webアプリ開発の土台から理解する。

RequestParamやRequestBodyの暗記だけでは見えにくい、Web通信の基本原則を整理できます。

  • HTTPの仕組みから理解したい
  • RESTやURIの設計意図を学びたい

当サイトはAmazonアソシエイト・プログラムの参加者です。価格・在庫・配送条件はAmazonでご確認ください。

この記事とあわせて読みたい

まとめ

@GetMappingは一覧や詳細などの参照処理、@PostMappingは登録や申請などサーバーの状態を変更する処理へ使います。Controller共通のパスはクラスの@RequestMappingへまとめると、各メソッドの役割を読みやすくできます。

削除をGETにしないこと、登録成功後にredirectすること、HTMLやJavaScriptとControllerのHTTPメソッドを揃えることが、現場で特に重要な確認点です。アノテーションの形ではなく、操作の意味からHTTPメソッドを選びましょう。

-Spring
-, , ,