빰_s

(25.02.02) RequestBody vs RequestParam vs PathVariable 본문

Java/Spring

(25.02.02) RequestBody vs RequestParam vs PathVariable

Job_E 2025. 2. 2. 23:56

스프링을 사용할 때 컨트롤러에서 요청에 대한 파라미터 정보를 추가하고자 할 시, 위 세가지 어노테이션 (@ : Annotation) 이 추가된 파라미터를 사용하여 요청을 진행하게 된다.

예를 들자면,

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam String id) {
    return "ID: " + id;
}

 

컨트롤러에 위 메소드를 작성한 뒤 어플리케이션을 실행했을 때, id 파라미터에 입력된 값을 이용해서 API를 꾸밀 수 있다.

해당 글에선 이와 같이 파라미터로 API를 꾸밀 수 있는 이 세가지 어노테이션에 대해 알아보자.

 

1. RequestBody

Json 데이터를 원하는 타입의 객체로 받고자 할 때 사용한다.

Json 형식으로 명시된 데이터를 DTO 객체로 묶어서 API에 포함시킬 때 사용하는 예시가 있다.

 

 public ResponseEntity<AuthDto> login(@RequestBody AuthReqDto authDto) {

        AuthDto auth = switch (authDto.getProvider()) {
            case "google" -> googleLoginService.login(authDto);
            case "kakao" -> kakaoLoginService.login(authDto);
            case "naver" -> naverLoginService.login(authDto);
            case "apple" -> appleLoginService.login(authDto);
            default -> throw new IllegalArgumentException("Invalid provider");
        };

        // preuser일 경우 201 status code로 응답
        if (auth.getUserInfo().getUserType().equals("preuser")) {
            return ResponseEntity.status(201).body(auth);
        } else {
            return ResponseEntity.ok(auth);
        }
    }

이건 현재 내가 진행중인 프로젝트에서 구현한 다중 플랫폼 로그인 메소드다.

RequestBody에서 AuthReqDto 형식으로 Json 형식의 데이터를 하나의 객체로 묶어 전달하며, 전달 여부 및 유저 정보에 따라 그 진행 경과가 예외일지 200일지 201일지 나뉘게 된다.

 

이에서 볼 수 있듯, RequestBody는 Http 요청의 Body를 자바 객체로 받을 수 있게 해주며, 주로 비동기 처리 구현시 사용된다.

 

2. RequestParam

이는 쿼리 스트링에서 필요한 값을 가져온다고 보면 된다.

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam String id) {
    return "ID: " + id;
}

해당 어노테이션이 명시된 매개변수 값은 반드시 파라미터 값이 넘어와야 하며, 그렇지 않을 시 400(Bad Request) 에러가 발생하게 된다.

다만, 비필수 처리도 가능하다.(※ @RequestParam 앞에 (required = false) 그대로 추가)

이때 파라미터로 넘어오지 않은 값은 null이 넘어오는데, 이땐 defaultValue를 사용해서 기본 값을 설정해줄 수 있다.

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false, defaultValue="charlie") String id ) {  // // id는 비필수 값이며 미입력시 값은 "charlie"
    return "ID: " + id;
}

 

3., PathVariable

URL 경로의 일부를 파라미터로 사용하고자 할 때 사용, 즉 URL 경로에서 값을 가져온다.

예를 들어 요청 결과, localhost:8080/users/charlie와 같은 url이 넘어왔다고 가정했을 때, 

@RequestMapping("/users/{userid}", method=RequestMethod.GET)
public String getUser(@PathVariable String userId) {
  // implementation omitted...
}

charlie는 url 템플릿 변수의 값으로써, getUser 메소드의 매개변수 userId의 요청 값으로써 바인딩이 이뤄진다.

여기서 url 템플릿 변수 이름과 메소드 매개변수 이름이 반드시 같아야 하는 것은 아니며, 여러개의 PathVariable을 사용하게 될 경우, url 템플릿 변수 또한 PathVariable로 지정된 매개변수 숫자에 맞게 설정되어야 한다.

 

@RequestMapping("/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET)
public String findPet(@PathVariable String ownerId, @PathVariable String petId
, Model model) {
  Owner owner = ownerService.findOwner(ownderId);  
  Pet pet = owner.getPet(petId);  
  model.addAttribute("pet", pet);  
  return "displayPet"; 
}
Comments