@RestController で別のエンドポイントに同じ処理を行わせる方法(エイリアス)

たとえばECサイトで、購入した商品の「変更処理 (/edit) 」と「キャンセル処理 (/cancel) 」があったとします。

でもサーバ側では実際には同じPUTリクエストで行われており、違いは渡ってくるPUTオブジェクトの中身だけ(変更点が数量フィールドなのか削除フラグなのかだけ)、ってことがありえます。

ただUI的にURLは分けないといけなかったりします。

そういう場合に便利です。

まず何も考えなければこうやって書いちゃいますね。

    @PutMapping("/edit")
    @ResponseStatus(HttpStatus.OK)
    public void updatePurchasedData(@RequestBody PurchaseDataPutRequest request) {
        requestProcessor.update(request);
    }

    @PutMapping("/cancel")
    @ResponseStatus(HttpStatus.OK)
    public void updatePurchasedData(@RequestBody PurchaseDataPutRequest request) {
        requestProcessor.update(request);
    }

@PutMappingvalue が違うだけで他は同じ、っていうのがいかにもダサいです。

わかりやすいDRY原則違反でもあります。

そこでこう書きましょう。

    @PutMapping({"/edit", "/cancel"})
    @ResponseStatus(HttpStatus.OK)
    public void updatePurchasedData(@RequestBody PurchaseDataPutRequest request) {
        requestProcessor.update(request);
    }

Spring Framework のソースを見てみるとわかりますが、

RequestMapping の valueString[] 型になってます。

なのでこういうことが可能なんですね〜