개념.log/Spring

@RequestMapping

_2J 2023. 2. 23. 23:48

2023.02.23 - [🐢 Study/Spring boot] - 2. REST-API 설계

 

2. REST-API 설계

REST-API (Representational State Transfer API) REST API 제대로 알고 사용하기 : NHN Cloud Meetup REST API 제대로 알고 사용하기 meetup.nhncloud.com 스프링 부트를 활용한 REST-API 서버 구성 스프링 부트 프레임워크는 애

ljg960730.tistory.com

 

RequestMappingHandlerMapping

 

DispatcherServlet이 클라이언트의 요청을 처리할 때는 RequestMappingHandlerMapping 컴포넌트의 메서드를 이용하여 클라이언트의 요청과 매칭되는 핸들러 메서드를 조회할 수 있다.

 

1. @GetMapping

2. @DeleteMapping

3. @PostMapping

4. @PutMapping

 

 

 

1. @GetMapping

@RequestMapping(method=RequestMethod.GET)

 

GetMapping @Interface

@Target({ElementType.METHOD})	-(1)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = {RequestMethod.GET})
public @interface GetMapping {
    @AliasFor(annotation = RequestMapping.class)
    String name() default "";

    @AliasFor(annotation = RequestMapping.class)
    String[] value() default {};	-(2)

    @AliasFor(annotation = RequestMapping.class)
    String[] path() default {};		-(2)

    @AliasFor(annotation = RequestMapping.class)
    String[] params() default {};	-(3)

    @AliasFor(annotation = RequestMapping.class)
    String[] headers() default {};	-(4)

    @AliasFor(annotation = RequestMapping.class)
    String[] consumes() default {};	-(5)

    @AliasFor(annotation = RequestMapping.class)
    String[] produces() default {};	-(6)
}

 

(1) @RequestMapping과 달리 @GetMapping은 메서드 선언부에만 설정할 수 있다.

(2) 클라이언트가 요청하는 URI 설정

(3) 파라미터 이름과 매칭

(4) 헤더이름과 매칭

(5) Content-Type 헤더값과 매칭

(6) Accept 헤더값과 매칭

 

 

@GetMapping(path = "/hotels")
public void getHotels() {
    ...
}

@GetMapping(path = "/hotels", params = "isOpen")
public void getHotelsByOpen() {
    ...
}

URI 경로는 같지만, isOpen 과 같은 특정 파라미터를 포함할 때 이를 처리하는 핸들러 메서드를 구분해야 하는 경우 위와 같이 구분하여 사용 가능하다.

 

 

 

 

GetMapping Attribute

 

[Path]  ant-style path pattern

 

@GetMapping 애너테이션의 path 속성 값에는 ant-style path pattern 문자열을 사용하여 설정 할 수 있다. 

ant-style path pattern 에서 사용할 수 있는 패턴문자는 '*', '**', '?' 가 있다. 

 

1) *

- 0개 이상의 문자만 매칭할 수 있다.

- @GetMapping(path="/hotels/*")으로 선언된 메서드는 '/hotels/12041'은 매칭할 수 있지만 '/hotels/12041/rooms'는 매칭할 수 없다.

 

2) **

- 0개 이상의 문자와 디렉터리를 매칭할 수 있다.

- @GetMapping(path="/hotels/**")으로 선언된 메서드는 '/hotels/12041', '/hotels/12041/rooms'등 하위 디렉터리가 몇개든 상관없이 모두 매칭가능하다.

 

3) ?

- 한 개의 문자와 매칭된다.

- @GetMapping(path="/hotels/?")으로 선언된 메서드는 '/hotels/1'은 매칭할 수 있지만 '/hotels/12'는 매칭할 수 없다.

 

 

 

 

path, value, name, consumes, produces에 설정된 값은 OR 연산으로 동작하고, params, headers에 설정된 속성값은 AND 연산으로 동작한다.

 

@GetMapping(path={"/hotels", "/rooms"})

- GET /hotels , GET /rooms 요청 모두 매핑할 수 있는 설정이다.

 

@GetMapping(path="/hotels", params={"isOpen", "hasVacancy"})

- GET /hotels?isOpen=true&hasVacancy=true 요청을 매핑할 수 있는 설정이다.

 

@GetMapping(path={"/hotels", "/rooms"}, params={"isOpen", "hasVacancy"})

- GET /hotels?isOpen=true&hasVacancy=true, - GET /rooms?isOpen=true&hasVacancy=true 요청을 매핑할 수 있는 설정이다.

 

 

 

 

 

@PathVariable

사용자가 요청한 REST-API의 URI에서 특정 위치에 있는 데이터를 뽑을 떄 사용한다.

@PathVariable을 사용하여 뽑아낸 데이터는 핸들러 메서드의 인자로 주입 가능하다. 데이터를 주입할 인자에 @PathVariable 애너테이션을 정의하면 된다. 이때, @GetMapping 의 path속성에는 리소스 변수가 선언되어 있어야하며, @PathVariable에는 주입할 리소스 변수의 이름을 선언해야 한다.

 

@GetMapping(path="/hotels/{hotelId}/rooms/{roomId}")
public HotelRoomResponse getHotelRoom(
        @PathVariable(value="hotelId") Long hotelId,
        @PathVariable(value="roomId") Long roomId) {

    ...
    
}

 

 

@RequestParam

Http 파라미터는 이름과 값으로 구성되고 &를 사용하여 여러 파라미터를 조합 전달할 수 있다.

 

@GetMapping(path = "/hotels/{hotelId}/rooms/{roomNumber}")
public HotelRoomResponse getHotelRoomByPeriod(
        @PathVariable Long hotelId,
        @PathVariable String roomNumber,
        @RequestParam(value = "fromDate", required = false) @DateTimeFormat(pattern = "yyyyMMdd") LocalDate fromDate,
        @RequestParam(value = "toDate", required = false) @DateTimeFormat(pattern = "yyyyMMdd") LocalDate toDate) {
    ...
}

 

필수여부를 결정하는 required 옵션 기본값은 true이다.

name 또는 value 에 설정된 이름과 매칭되는 파라미터 값이 null 이거나 비어있는 경우 defaultValue 옵션을 통해 기본 값을 설정할 수 있다.

 

 

 

 

2. @DeleteMapping

https://jump-developer.tistory.com/41

 

[Restuful 학습] - DeleteMapping 실습 및 예제

package com.example.demo.user; @RestController public class UserController { private UserDaoService service; public UserController(UserDaoService service) { this.service = service; } @DeleteMapping("/users/{id}") public void deleteUser(@PathVariable int id

jump-developer.tistory.com

 

@GetMapping 과 사용방법은 동일하다. 

 

REST 규약에 따라 보통 데이터를 삭제하기 위한 Method로 사용된다.

 

 

 

3. @PostMapping

4. @PutMapping

 

PostMapping, PutMapping 애너테이션도 앞글에서 설명한 GetMapping, DeleteMapping 애너테이션과 사용법, 속성은 동일하다.

 

 

PostMapping Example

@PostMapping(path = "/hotels/{hotelId}/rooms")
public ResponseEntity<HotelRoomIdResponse> createHotelRoom(
        @PathVariable Long hotelId,
        @RequestBody HotelRoomRequest hotelRoomRequest
) {
    System.out.println(hotelRoomRequest.toString());

    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add(HEADER_CREATED_AT, DATE_FORMATTER.format(ZonedDateTime.now()));
    HotelRoomIdResponse body = HotelRoomIdResponse.from(1_002_003_004L);

    return new ResponseEntity(body, headers, HttpStatus.OK);
}

 

 

@RequestBody 애너테이션은 클라이언트에서 전송한 요청 메시지의 바디를 언마셜링하여 자바 객체로 변환한다.

애너테이션이 정의된 인자의 클래스 타입을 사용하므로 HotelRoomRequest객체로 언마셜링 된다.

변환된 객체는 hotel RoomRequest 인자에 주입된다. 

 

### REST-API 요청
POST /hotels/{hotelId}/rooms

{
	"roomNumber": "west-3928",
	"roomtype": "double",
	"originalPrice": "150.00"
}
@Getter
@ToString
public class HotelRoomRequest {

    private String roomNumber;
    private HotelRoomType roomType;
    private BigDecimal originalPrice;

}