오늘은 PutMapping과 DeleteMapping에 대해 알아보자.
전체적인 방식은 GetMapping, PostMapping과 비슷하니 자세한 설명은 생략하고, 이전에 배운 방식들을 한 번씩 복습해보는 방법을 채택하려고 한다.
GetMapping : https://velog.io/@hunzz/spring-boot-get
PostMapping : https://velog.io/@hunzz/spring-boot-post
PUT 메서드는 POST 메서드와 마찬가지로 HTTP 메시지 바디 부분에 JSON 형식으로 데이터를 전송하기 때문에, 메서드 파라미터 앞에 @RequestBody 어노테이션을 사용한다.
DTO 객체를 통해서 JSON 데이터를 받아보도록 하겠다.
@RestController
@RequestMapping("/api/put")
public class PutController { }
시작하기 앞서, 다음과 같이 Controller를 만들고 경로를 지정해주자.
public class Car {
private String name;
@JsonProperty("car_number")
private String carNumber;
... (코드 중략) ...
(대충 모든 멤버변수에 getter/setter 만들어져 있는 내용)
}
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class PutRequest {
private String name;
private int age;
private ArrayList<Car> carList;
... (코드 중략) ...
(대충 모든 멤버변수에 getter/setter 만들어져 있는 내용)
}
@PutMapping("/request-body/dto")
public PutRequest put(@RequestBody PutRequest userRequest) {
return userRequest;
}
자, 본인이 보유한 차의 종류를 담기위해서 ArrayList를 선언했고, 그 ArrayList는 Car 클래스의 객체들을 담을 예정이다. 어? Car 클래스에는 지난 시간에 배운 @JsonProperty 어노테이션이 붙어있다! 아 맞다. JSON 데이터 안의 car_list 리스트에서 'car_number'가 snake_case로 선언되어 있으니, camelCase로 선언된 Car 클래스의 멤버 변수 carNumber와 매칭하려고 하는구나!
여기까지는 이해가 됐다.
근데... DTO 클래스(PutRequest) 상단에 @JsonNaming 어노테이션은 도대체 뭘까?
지난 시간 PostMapping을 설명하면서 변수명의 case를 맞추는 방법이 하나 더 있다고 얼핏 예고편을 날렸었는데, @JsonNaming이 바로 변수명의 case를 매칭하는 또 다른 방법인 것이다!
case 충돌이 일어날 수 있는 DTO 클래스 위에 @JsonNaming 어노테이션을 선언하고, 그 value 값으로 PropertyNamingStrategies.SnakeCaseStrategy.class를 설정해주면 된다. 이름에서 눈치챌 수 있듯이, Object Mapper라는 모듈이 동작할 때, DTO의 camelCase로 선언된 변수를 snake_case로 인식할 수 있도록 도와주는 어노테이션이다.
아직 데이터베이스에 접근하는 방법은 알려주지 않았기 때문에,
단순히 DTO 객체를 리턴해서 HTML Body에 출력하는 수준에서 마무리하겠다.
@RestController
@RequestMapping("/api/delete")
public class DeleteController { }
DeleteController를 만들어주고 @RestController 어노테이션을 붙여주고,
그동안 했던 방식과 똑같이 @RequestMapping으로 경로까지 지정해주자.
DELETE 메서드는 더 간단하고 쉽다. GET 메서드와 마찬가지로 Query String으로 값을 서버에 전달하기 때문에, @RequestParam이나 @PathVariable 어노테이션을 메서드 파라미터 앞에 붙인다.
이번 예시에서는 @PathVariable을 복습해보자.
@RestController
@RequestMapping("/api/delete")
public class DeleteController {
@DeleteMapping("/path-variable/{userID}")
public void delete(@PathVariable String userID) { }
}
GetMapping에서 배웠듯이, @PathVariable은 변수를 경로에 넣어 데이터를 전달하는 어노테이션이다. 위에서 언급했듯이, DELETE는 HTTP의 메시지 바디가 아닌 Query String으로 데이터를 서버 측에 전달해주기 때문에, DELETE 메서드의 파라미터 수는 많지 않고 제한적이다.
보통 DELETE 메서드에서는 삭제할 엔티티의 primary key에 해당하는 값을 전달하는게 일반적인데, 아직 이게 무슨 말인지 이해 못할 것이다. 나중에 데이터베이스에 접근하는 방법을 배울 때 구체적으로 설명해주겠다.
아무튼, delete 메서드에서는 사용자의 고유한 ID를 파라미터로 전달받아, 해당 ID에 해당하는 User 객체를 데이터베이스에서 삭제하는 로직을 처리하면 될 것이다. 지금은 특별히 할 수 있는게 없으므로 중괄호 안을 비워놓겠다.
지금까지, GET, POST, PUT, DELETE 메서드를 사용할 때,
어떤 방식으로 클라이언트로부터 데이터를 받아올 수 있는지 알아보았다.
자, 다음 시간부터는 이제 Request를 서버에서 처리한 후,
어떤 방식으로 Response를 돌려주는지 알아보도록 할 예정이다.
계속 언급하지만, spring-boot 시리즈를 읽으시기 전에
web 시리즈를 정독하셔서 최소한 HTTP의 개념을 알고오셔야 합니다!