[Spring] 실무에서 활용하는 @PathVariable 사용법, @RequestParam 차이
@PathVariable
스프링에서 @PathVariable 어노테이션을 사용하면 URI의 템플릿 변수를 메서드 파라미터에 바인딩할 수 있다.
예를 들어
https://code-lab1.tistory.com/{idx}
위의 {idx}는 URI 템플릿 변수(이하 템플릿 변수)로 값이 바뀌는 가변형 변수이다.
실제로는 https://code-lab1.tistory.com/127
위와 같이 실제 값이 들어가게 된다.
이처럼 REST API로 전송되는 템플릿 변수를 메서드의 파라미터에 바인딩할 수 있다.
value 속성
@RestController
public class SomethingController{
@GetMapping("/student/{name}")
public ResponseEntity getStudentInfo(@PathVariable(value="name") String studentName){
System.out.println(studentName);
...
}
}
위와 같이 Controller의 메서드에서 @PathVariable을 사용할 수 있다.
그럼 실제로 REST API를 호출할 때 전송된 템플릿 변수 {name}의 값이 getStudentInfo 메서드의 studentName 파라미터에 바인딩된다.
예를 들어 https://..../student/gil-dong 을 호출한다면,
getStudentInfo 메서드의 studentName은 "gil-dong"이 될 것이다.
위와 같이 템플릿 변수와 메서드의 파라미터 이름이 다르다면 @PathVariable 어노테이션에 value 옵션으로 템플릿변수의 이름을 지정해줘야 한다.
Value 속성 생략
@RestController
public class SomethingController{
// 이름이 같다면 value 옵션 생략 가능
@GetMapping("/student/{name}")
public ResponseEntity getStudentInfo(@PathVariable String name){
System.out.println(studentName);
...
}
}
만약 위와 같이 템플릿 변수와 파라미터의 이름이 같다면 @PathVariable에서 value 옵션을 생략해도 된다.
여러 개의 템플릿 변수
@RestController
public class SomethingController{
@GetMapping("/student/{name}/{age}")
public ResponseEntity getStudentInfo(
@PathVariable String studentName
@PathVariable String age
){
System.out.println(studentName +", " + age);
...
}
}
위와 같이 여러 개의 템플릿 변수를 받을 수도 있다.
Map<String, String> 형태
@RestController
public class SomethingController{
@GetMapping("/student/{name}/{age}")
public ResponseEntity getStudentInfo(@PathVariable Map<String, String> paramMap){
System.out.println(paramMap.get(name) +", " + paramMap.get(age) );
...
}
}
Map<String, String> 형태를 사용하면 많은 수의 템플릿 변수를 쉽게 받을 수 있다.
Map의 Key에는 템플릿 변수의 이름(ex : name, age)이 들어있고, value에는 실제 전송된 값들이 들어있다
따라서 paramMap.get([key])와 같은 형식으로 실제 값을 꺼낼 수 있기 때문에 매우 편리하다.
많은 수의 템플릿 변수를 받아야 한다면 고려해볼만 하다.
@RequestParam과의 차이
@RequestParam은 URI 쿼리 파라미터의 값을 메서드의 매개변수에 바인딩해준다.
예를 들어
https://www.code-lab1/v1/board?page=1&pageSize=10
@GetMapping("/v1/board")
public ResponseDto<BoardListRes> getBoardList(
@RequestParam(value="page") Integer page,
@RequestParam(value="pageSize") Integer pageSize){
System.out.println(page + ", " + pageSize); // 1, 10
}
위와 같이 '?' 기호 뒤에 page=1, pageSize=10 같은 쿼리 파라미터의 값을 메서드의 매개변수에 바인딩해주는 것이다.
코드를 보면 차이를 더 확연히 알 수 있다.
참고)
또한 @RequestParam은 같은 이름의 쿼리 파라미터 값을 여러 개 받아올 수 있다.
https://www.code-lab1/v1/board?pages=1,2,3,4
예를 들어 위와 같이 ',' 구분자를 통해 여러 개의 값을 가져올 수 있다.
하지만 @PathVarible은 여러 개의 값을 가져올 수 없다.
또한 @RequestParam은 default 값을 지정할 수 있지만 @PathVariable은 지정할 수 없다.
이러한 점들을 고려하여 @RequestParam을 쓸지, @PathVariable을 쓸지 고민해봐야한다.
물론 두 개의 어노테이션을 섞어서 사용할 수도 있다.