본문 바로가기
쿤즈 Dev/Spring Boot

[Spring Boot] @RequestParam @RequestBody @PathVariable 차이를 알아보자

by Koonz:) 2022. 2. 24.
728x90

지난 포스팅에서는 API를 간단하게 호출해서 View형태로 페이지를 응답할지, 아니면 데이터의 형태로 응답할지에 대해서 ㅇ라아보았습니다.

2022.02.18 - [쿤즈 Dev/Spring Boot] - [Spring Boot] 간단한 API 만들어서 테스트 해보기(feat. @Controller vs @RestController)

 

[Spring Boot] 간단한 API 만들어서 테스트 해보기(feat. @Controller vs @RestController)

지난 포스팅에서 스프링 부트 프로젝트를 생성하고 Run 하여 Whitelabel이 나오는 화면까지 확인해 보았습니다. 2022.02.16 - [쿤즈 Dev/Spring Boot] - [Spring Boot] 간단하게 웹 프로젝트 개발 시작하기 [Sprin..

koonsland.tistory.com


그래서 @Controller와 @RestController의 차이를 알 수 있었어요.

이번 포스팅에서는 브라우저로부터 혹은 클라이언트로부터 HTTP 통신을 할 때, 데이터를 받은 방법에 대해서 알아볼게요.


데이터를 받을 수 있는 종류

클라이언트, 대표적으로 브라우저 또는 Postman을 통해서 간단하게 API 테스트를 해볼 수 있는데요. 이렇게 테스트시에 넘겨줄 수 있는 데이터의 종류에는 3가지가 있습니다.

  • URL path를 이용한 값
  • URL parameter 를 이용한 값
  • HTTP Body를 이용한 값

받을 수 있는 데이터의 유형으로 보니 어떠한 어노테이션을 써야 할지 대략적으로 눈에 보이는 것 같습니다. 그럼 하나씩 실제 사용하는 방법을 알아보도록 할게요.


테스트용 데이터 메모리에 준비

API 테스트를 하기 위해서는 가짜 데이터가 필요합니다. 그래서 데이터를 준비해보도록 할게요. 우선은 Member 클래스를 만들어 주도록 합니다.

package com.koonsland.board.api;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Member {
    private Long id;
    private String name;
}

이렇게 클래스를 만들어 놓고 Spring Boot 애플리케이션을 실행했을때, Member 클래스에 데이터를 넣고 List 형태로 데이터를 가지고 있기 위해서 Controller 클래스에 이를 저장합니다.

 

클래스는 MemberController라는 이름으로 만들어 주었습니다. 그리고 @RestController 어노테이션을 붙여주어 데이터를 Response으로 전달하도록 했어요.

package com.koonsland.board.api;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/v1")
public class MemberController {

    public static List<Member> list = new ArrayList<>();

    public MemberController() {
        list.add(new Member(1L, "Ironman"));
        list.add(new Member(2L, "Hulk"));
        list.add(new Member(3L, "Captain"));
    }

    @GetMapping("/members")
    public List<Member> getMembers() {
        return list;
    }
}

사실 실제로 데이터를 이렇게 생성자를 통해서 주입하지는 않습니다. 이 컨트롤러에서는 보통 Service 혹은 Repository에 관련된 클래스를 생성자를 통해서 주입하지만 지금은 테스트 용도로 데이터를 메모리에서 가지고 있기 위함입니다. 이제 API를 만들어서 데이터를 가져오는지 확인해 볼게요.

넣은 데이터를 JSON 형태로 잘 내려보내고 있네요. 이제 Parameter들을 받는 방법에 대해서 하나씩 알아보겠습니다.


PathVariable 사용 방법

가장 처음 알아볼 내용은 PathVariable입니다. 이 경우는 Rest API를 사용시 URL 주소와 함께 오는 값을 받을 수 있습니다. 예를 들어서 다음과 같은 API 주소가 있다고 가정하겠습니다.
GET /api/v1/members/1

API를 Controller 클래에서 만들어 주도록 합니다.

@GetMapping("/members/{id}")
public Member getMember(@PathVariable("id") Long id) {
    List<Member> members = list.stream()
            .filter(member -> member.getId() == id)
            .collect(Collectors.toList());

    return members.isEmpty() ? null : members.get(0);
}

 

위 API는 회원목록중 1번 회원에 해당하는 회원 정보를 가져오는 API입니다. 이때 1번이라는 값은 URL 주소로 이용되는 값이지만 이 값을 @PathVariable이라는 어노테이션을 이용해서 가져올 수 있습니다.

 

@GetMapping 어노테이션에 내용을 보시면 {id} 라는 값을 받도록 했어요. 그리고 이는 @PathVariable("id")를 이용해서 받습니다. 단 이 값의 타입은 Long 타입으로 정해주었고, 이럴 경우 이 값으로 알아서 변환해서 값이 저장됩니다. 나머지는 매칭 되는 값을 찾기 위한 로직입니다.

2021.08.18 - [쿤즈 Dev/Java] - [Java] stream() 메소드를 이용해서 Collection 객체 가공하는 방법

 

[Java] stream() 메소드를 이용해서 Collection 객체 가공하는 방법

Java를 사용해서 애플리케이션을 만들고, 또 웹을 만들다 보면 Java8 버전의 stream() 메서드를 많이 사용하게 됩니다. 여러 번의 반복된 작업을 굉장히 간략히 변경해서 사용하고, 또 객체들을 가공

koonsland.tistory.com

 


RequestParam 사용 방법

두 번째 알아볼 내용은 RequestParam입니다. 이 경우는 보통 GET방식에서 주로 사용하는 방법입니다. 예를 들어서 회원 전체를 리스트로 가져오고자 한다면 다음과 같은 API를 만들 수 있습니다.
GET /api/v1/members

 

이 경우에는 회원 전체를 가져온다고 할 때, 만약 회원수가 너무 많다면 어마어마한 양의 데이터가 한꺼번에 내려올 수 있습니다. 그래서 이런 경우에는 보통 페이징을 합니다. 한 페이지에 10개씩 가져오되 지금은 첫 번째 페이지만 가져온다 처럼 말이죠. 이럴 때 우리는 URL 주소 뒤에 파라미터(Parameters)를 넣을 수 있습니다.

GET /api/v1/members?page=1&lmit=10

 

이 경우 @RequestParam 어노테이션을 사용해서 page와 limit 값을 Controller에서 받을 수 있습니다. 지금은 페이징을 알아보는 시간이 아니기 때문에 다른 예로 회원 이름이 Hulk인 데이터를 가져오도록 해볼게요.

GET /api/v1/members?name=Hulk

 

위와 같은 API를 만들어볼 건데요. 기존에 있던 getMembers() 메서드를 수정해 보도록 하겠습니다.

@GetMapping("/members")
public List<Member> getMembers(@RequestParam("name") @Nullable String name) {
    return name == null ? list :
            list.stream()
                    .filter(member -> member.getName().equalsIgnoreCase(name))
                    .collect(Collectors.toList());
}

이번에는 GET 방식에서 ?(물음표) 뒤에 들어오는 Parameters를 가져오기 위해서 @RequestParam이라는 어노테이션을 사용했어요. 그리고 추가적으로 @Nullable은 값이 null로 들어와도 에러를 내보내지 않기 위한 어노테이션입니다.

 

name=Hulk를 URL 주소에 입력하면 name이라는 값에 대한 value 값을 name 변수에 넣어서 값을 가지고 메서드 내부로 들어오게 됩니다. 결과를 확인해 볼게요.


RequestBody 사용 방법

마지막으로 알아볼 내용은 RequestBody입니다. 이 경우는 POST, PUT 메서드를 이용할 때 사용되는 방법입니다. URL에 붙여서 주는 것이 아니라 HTTP 메서드의 Body에 값을 담아서 서버로 던지고 서버에서는 Body에 있는 값을 이용해서 데이터를 저장하거나 수정할 수 있는 방법입니다. 새로운 회원을 저장한다고 가정해볼게요.
POST /api/v1/members
Body { "id":4, "username":"Thor"}

 

Body에 값을 담을 때에는 보통 HTML의 Form을 이용하거나 Javascript의 Ajax, Fetch API를 사용합니다. 예제에서는 Ajax, Fetch를 사용하는 부분이 중점이 아니기 때문에 Postman을 이용해서 데이터를 저장해 보고 데이터 전체를 가져와 보도록 할게요.

@PostMapping("/members")
public String saveMembers(@RequestBody Member member) {
    list.add(member);

    return "success";
}

데이터를 받을 때에는 @RequestBody 어노테이션을 붙여서 사용합니다. 그리고 그 뒤에 받을 데이터의 타입을 지정해서 데이터를 받도록 합니다. 지금은 Member와 같은 데이터 형태를 보내기 때문에 이 타입으로 받아볼게요. Postman을 열어줍니다.

 

 

새로운 값을 저장했고 결과로 우리가 원하는 success 값을 받았습니다. 그럼 정상적으로 값이 저장이 되었는지 확인해 볼게요. 기존에 만들었던 /api/v1/members API를 호출해줍니다.

 

방금 넣었던 id 4번의 Thor 값이 정상적으로 들어간 것을 볼 수 있어요.


이번 포스팅에서는 Controller에서 데이터 parameters를 받는 3가지 방법에 대해서 알아보았어요. 그리고 값은 @PathVariable, @RequestParam, @RequestBody 어노테이션들을 통해서 받을 수 있다는 사실도 알았습니다. Spring Boot는 이러한 데이터들을 굉장히 쉽게 받을 수 있도록 구성되어 개발자로 하여금 개발에 더 집중할 수 있게 해 주는 것 같습니다. 도움이 되셨으면 합니다. 이상입니다.

댓글