스프링 부트로 만든 RESTful HTTP API 코드를 다시보며 리팩토링 하는 중에
굉장히 불편해보이는 부분을 발견했고 해결 하고 싶었다. 코드가 어떻게 되어있었냐면.....
@PatchMapping(value = "/foo/{id}")
@Transactional
public ResponseEntity<Object> updateSomething(@PathVariable(name = "id") Long id,
@RequestParam(name = "state",required = false)String state,
@RequestParam(name= "name",required = false)String name) {
if(state != null && name == null){
// request URL : /foo/{id}?state=value 일때
fooRepository.doSomethingWithState(state);
} else if(name != null&& state == null){
// request URL : /foo/{id}?name=value 일때
fooRepository.doSomethingWithName(name);
} else {
throw new 무슨무슨익셉션();
}
return ResponseEntity.ok("데이터 리턴");
}
이런식으로 되어있었다....
한 가지의 자원에 대하여 여러개의 PATCH 요청을 구현해야할때 같은 Request URL에 대하여 파라미터로 식별하여 구분하여 매핑을 해줘야하는데 당시에는 그걸 몰라서 고민 없이 빠르게 구현하려고 저렇게 코드를 작성했었다.
지금은 수정 속성이 2개지만 수정대상이 10개 정도만 되도.... 코드가 아주 끔찍해질 것 같다. 또 단일 책임 원칙도 위배하고 있다.
이렇게 하면 되는거 아닌가? 라고 생각했다면 당신은 컨트롤러를 다시 공부해야한다!!!
해당 속성을 모르는 상황에서 구글링 키워드를 뭐라고 해야 하는지 몰라 커뮤니티를 돌며 질문을 했는데 만족스러운 대답을 얻지 못했고 아쉬운 마음에
이것 저것 뒤져보다가 해당 속성을 발견했다.
-> 공식문서
해당 속성을 사용하면 파라미터의 key와 value를 이용하여 매핑할 수 있게된다.
해당 속성에서 지원하는 표현식은
@PatchMapping(value = "/foo/{id}",params = "state")
public String updateState(@RequestParam(name = "state")String state){
return "State!!!";
}
@PatchMapping(value = "/foo/{id}",params = "name")
public String updateName(@RequestParam(name = "name")String name){
return "Name!!!";
}