Spring으로 REST API를 개발하다 보면 다음과 같은 어노테이션을 자주 만나게 된다.
- @PathVariable
- @RequestParam
- @RequestHeader
- @RequestBody
처음에는 각각의 사용법만 외웠지만, 프로젝트를 진행하면서 “왜 어떤 값은 @PathVariable을 쓰고, 어떤 값은 @RequestBody를 사용할까?“라는 의문이 생겼다.
결론부터 말하면 이 네 가지 어노테이션은 HTTP 요청의 서로 다른 위치에서 데이터를 가져오기 위한 어노테이션이다.
이번 글에서는 HTTP 요청의 구조부터 시작해서 각각의 역할과 사용 시점을 정리해보려고 한다.
HTTP 요청의 구조
클라이언트(Postman, 브라우저, 앱 등)가 서버로 요청을 보내면 요청은 크게 네 부분으로 나눌 수 있다.
PUT /schedules/10?sort=desc HTTP/1.1
Authorization: Bearer abcdefg
{
"title":"수정된 일정",
"author":"유림",
"password":"1234"
}
이 요청을 자세히 보면 데이터를 보낼 수 있는 위치가 여러 곳이라는 것을 알 수 있다.
URL
↓
/schedules/10
------------------------
Query String
↓
sort=desc
------------------------
Header
↓
Authorization
------------------------
Body
↓
JSON 데이터
Spring은 각각의 위치에서 데이터를 가져오기 위해 서로 다른 어노테이션을 제공한다.
| 데이터 위치 | spring 어노테이션 |
| URL | @PathVariable |
| Query String | @RequestParam |
| Header | @RequestHeader |
| Body(JSON) | @RequestBody |
1. @PathVariable
@PathVariable은 URL 경로(Path)에 포함된 값을 가져오는 어노테이션이다.
예를 들어 다음과 같은 URL이 있다고 하자.
GET /schedules/10
여기서
10
은 조회하려는 일정의 ID이다.
Controller는 다음과 같이 작성한다.
@GetMapping("/{scheduleId}")
public ScheduleResponse findSchedule(
@PathVariable Long scheduleId
) {
}
그러면 Spring은
/schedules/10
에서
10
을 추출하여
scheduleId = 10
으로 전달해준다.
즉 @PathVariable은 리소스를 식별하는 값(ID)을 전달할 때 사용한다.
REST API에서는 다음과 같이 사용하는 것이 일반적이다.
/users/3
/posts/100
/products/20
/schedules/10
모두 특정 리소스를 식별하는 URL이다.
2. @RequestParam
@RequestParam은 Query String의 값을 가져오는 어노테이션이다.
예를 들어
GET /schedules?author=철수
여기서
?author=철수
이 Query String이다.
Controller는 다음과 같이 작성한다.
@GetMapping
public List<ScheduleResponse> findSchedules(
@RequestParam String author
) {
}
그러면
author = "철수"
이 된다.
Query String은 주로
- 검색
- 정렬
- 필터링
- 페이지 번호
와 같은 조건을 전달할 때 사용한다.
예를 들어
/products?page=1
/products?sort=price
/users?age=20
/schedules?author=철수
모두 Query String을 이용한 요청이다.
3. @RequestHeader
@RequestHeader는 HTTP Header의 값을 가져오는 어노테이션이다.
예를 들어 로그인 기능을 구현하면 클라이언트는 토큰을 Header에 담아 보낸다.
Authorization: Bearer abcdefg12345
Controller에서는 다음과 같이 받을 수 있다.
@GetMapping("/users")
public String findUser(
@RequestHeader("Authorization") String token
) {
}
그러면
token
↓
Bearer abcdefg12345
가 된다.
Header에는 보통
- JWT Token
- Content-Type
- Authorization
- API Key
등과 같은 요청의 부가 정보를 담는다.
즉 Header는 데이터를 수정하거나 조회하는 값이라기보다 요청에 대한 메타데이터를 전달하는 공간이다.
4. @RequestBody
@RequestBody는 HTTP Body에 있는 JSON 데이터를 객체로 변환하는 어노테이션이다.
예를 들어 일정 수정 요청을 보낸다고 가정해보자.
PUT /schedules/10
{
"title":"수정된 제목",
"author":"철수",
"password":"1234"
}
Body에는 JSON 데이터가 들어있다.
Controller는 다음과 같이 작성한다.
@PutMapping("/{scheduleId}")
public ScheduleResponse updateSchedule(
@PathVariable Long scheduleId,
@RequestBody ScheduleUpdateRequest request
) {
}
Spring은 내부적으로 JSON을 읽어서
ScheduleUpdateRequest request = new ScheduleUpdateRequest();
객체를 생성하고
request.getTitle();
request.getAuthor();
request.getPassword();
를 사용할 수 있도록 만들어준다.
이 과정은 Jackson 라이브러리가 담당한다.
@RequestBody는
- 회원가입
- 로그인
- 게시글 작성
- 일정 생성
- 일정 수정
처럼 많은 데이터를 한 번에 전달할 때 사용한다.
실제 수정 API에서는 왜 두 개를 함께 사용할까?
예를 들어 일정 수정 API는 다음과 같이 작성한다.
@PutMapping("/{scheduleId}")
public ScheduleResponse updateSchedule(
@PathVariable Long scheduleId,
@RequestBody ScheduleUpdateRequest request
)
여기에는 두 가지 정보가 필요하다.
첫 번째는
어떤 일정을 수정할 것인가?
이다.
이 정보는
/schedules/10
처럼 URL의 ID를 사용한다.
두 번째는
무엇으로 수정할 것인가?
이다.
이 정보는
{
"title":"수정된 제목",
"author":"철수",
"password":"1234"
}
처럼 Body로 전달한다.
즉
@PathVariable
↓
수정 대상
------------------
@RequestBody
↓
수정할 데이터
라는 역할 분담을 하게 된다.
정리
| 어노테이션 | 데이터 위치 | 주요 사용 목적 |
| @PathVariable | URL | 리소스 식별(ID) |
| @RequestParam | Query String | 검색, 정렬, 필터링 |
| @RequestHeader | Header | 인증 정보, 토큰, 메타데이터 |
| @RequestBody | Body(JSON) | 생성 및 수정 데이터 전달 |
'개발공부 > SPRING' 카테고리의 다른 글
| Java Record를 사용하면 왜 getName()이 아니라 name()일까? (0) | 2026.07.12 |
|---|---|
| @NotNull, @NotEmpty, @NotBlank 차이점과 사용법 정리 (0) | 2026.07.11 |
| Lombok의 @RequiredArgsConstructor는 무엇이며 왜 사용할까? (0) | 2026.06.28 |
| setter 대신 Entity 메서드를 사용하는 이유 (0) | 2026.05.15 |
| 🚨ERROR -org.springframework.jdbc.datasource.init.CannotReadScriptException: Cannot read SQL script from class path resource (0) | 2024.05.27 |