リクエストマッピング(@Request Mapping)

- 要請を送った時、どのコントロールラーが呼び出されるべきか、どのような方式で処理するかを定義する。
- @Request Mapping Annotationを使って要請を特定のmethodとmappingし、mappingする方法は以下がある。

# URL で mapping をする
- Url呼び出しが来たら、このメソッドが実行されるようにマッピングする。
- method属性でHTTPメソッド(GET、POST、HEAD、PUT、PATCH、DELETE)を指定しなければ、HTTPメソッドと関係なく呼び出される。
    ```java
    @RequestMapping("/hello-basic", method = RequestMethod.GET)
    // 多重設定も可能である。
    // @RequestMapping({"/hello-basic", "/hello-go"}, method = RequestMethod.GET)
    public String helloBasic() {
        log.info("helloBasic");
        return "ok";
    }
    ```
- 縮約することもできる。
    ```java
    // @RequestMapping("/hello-basic", method = RequestMethod.GET)
    @GetMapping(value = "/hello-basic")
    public String helloBasic() {
        log.info("helloBasic");
        return "ok";
    }
    ```

# PathVariale(パス変数)でmappingする
- 最近好まれる方法だ。
- resourceパスに識別子を入れるスタイルである。 ex.mapping/userA , /users/1
    ```java
    @GetMapping("mapping/{userId}")
    // @PathVariable の名前とパラメータ名が同じであれば省略できる。
    // public String mappingPath(@PathVariable("userId") String data){
    public String mappingPath(@PathVariable String userId){
        //log.info("mappingPath userId = {}", data);
    		log.info("mappingPath userId = {}", userId);
        return "ok";
    }
    
    // http://localhost:8080/mapping/test1
    // ...mappingPath userId = test1
    ```
- いくつか入れることもできる。
    ```java
    @GetMapping("mapping/users/{userId}/orders/{orderId}")
    public String mappingPath(@PathVariable String userId, 
    													@PathVariable Long orderId){
        log.info("mappingPath userId = {}, orderId={}", userId, orderId);
        return "ok";
    }
    
    // http://localhost:8080/mapping/users/testA/orders/100
    // ...mappingPath userId = testA, orderId=100
    ```
- 会員管理をHTTP API で作ると考えると、下記のようにマッピングできるだろう。
    |<!-- -->|<!-- -->|<!-- -->|
    | --- | --- | --- |
    | 会員一覧照会 | GET | /users |
    | 会員登録 | POST | /users | 
    | 会員照会 | GET | /users/{userId} | 
    | 会員修正 | PATCH | /users/{userId} | 
    | 会員削除 | DELETE | /users/{userId} | 
    ```java
    @RestController
    @RequestMapping("/mapping/users")
    public class MappingClassController {
    
        @GetMapping
        public String user() {
            return "get users";
        }
    
        @PostMapping
        public String addUser() {
            return "post user";
        }
    
        @GetMapping("/{userId}")
        public String findUser(@PathVariable String userId) {
            return "get userId= " + userId;
        }
    
        @PatchMapping("/{userId}")
        public String updateUser(@PathVariable String userId) {
            return "update userId= " + userId;
        }
    
        @DeleteMapping("/{userId}")
        public String deleteUser(@PathVariable String userId) {
            return "delete userId= " + userId;
        }
    }
    ```

# その他
その他にも下記のような方法を使ってmappingをするのにあまり使わない。

< 特定のパラメータ条件で mappingする >

- paramsの中にあるものが要請urlにあってこそ呼び出される。
    ```java
    @GetMapping(value="/mapping-param", params = "mode=debug")
    public String mappingParam() {
        log.info("mappingParam");
        return "ok";
    }
    
    // http://localhost:8080/mapping-param 
    // 400, Bad Request, マッピング自体ができない
    
    // http://localhost:8080/mapping-param?mode=debug 
    // ...mappingParam 
    ```

< 特定のheaderで mappingする >

- 
    ```java
    @GetMapping(value = "/mapping-header", headers = "mode=bebug")
    public String mappingHeader() {
        log.info("mappingHeader");
        return "ok";
    }
    
    // http://localhost:8080/mapping-header 요청
    // 404, NotFound
    
    // 아래와 같이 헤더에 값 추가해서 요청
    // ...mappingHeader
    ```
    ![스크린샷 2023-09-30 20.45.40 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/590bc0e2-d411-7380-566c-4b4923af6473.png)

< Media type 条件で mappingする >

1. consumes=コントロールの立場で消費するもの（content-type）が正しいときにのみ実行されるようにすることができる。
    ```java
    @PostMapping(value = "/mapping-consume", consumes = "application/json")
    // @PostMapping(value = "/mapping-consume", consumes = {"text/plain", "application/json"})
    // @PostMapping(value = "/mapping-consume", consumes = MediaType.TEXT_PLAIN_VALUE)
    public String mappingConsume() {
        log.info("mappingConsumes");
        return "ok";
    }
    
    // ...mappingConsumes
    ```
    ![스크린샷 2023-10-01 21.19.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/d1b2c7df-0983-c8a0-8cc8-c1fc026069bb.png)
![스크린샷 2023-10-01 21.19.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/e75709df-c7fa-e5a0-0bd0-47b8e2eea6f0.png)

2. produce=コントロールの立場で生産(accept)することが正しい時だけ実行されるようにすることができる。
    ```java
    @PostMapping(value = "/mapping-produce", produces = "text/html")
    public String mappingProduce() {
        log.info("mappingProduces");
        return "ok";
    }
    
    // 正しくなければ、HTTP 406 (Not Acceptable) の返却
    // ...mappingProduces
    ```
    ![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567846/98ee8000-68e2-d3b1-2884-dfc3345526eb.png)