1. HTTP 요청의 구조

먼저 HTTP 요청이 실제로 어떻게 생겼는지 알아야 합니다. 브라우저나 Postman이 서버에 보내는 요청은 이런 구조입니다:

POST /api/posts?category=tech HTTP/1.1     ← 요청 라인 (메서드, URL, 버전)
Host: localhost:8080                        ← 헤더 시작
Content-Type: application/json
Authorization: Bearer eyJhbG...
                                            ← 빈 줄 (헤더와 바디의 경계)
{                                           ← 바디 시작
    "title": "제목",
    "content": "내용"
}

데이터가 담길 수 있는 위치는 4곳입니다:

1. Path Variable   → URL 경로 안         /api/posts/1        ← 이 "1"
2. Query Parameter → URL의 ? 뒤         /api/posts?page=0   ← 이 "page=0"
3. Request Body    → HTTP 바디 안        {"title": "제목"}
4. Request Header  → HTTP 헤더 안        Authorization: Bearer xxx

스프링은 각 위치에서 데이터를 꺼내는 전용 어노테이션을 제공합니다.


2. @PathVariable — URL 경로에서 꺼내기

URL의 일부를 변수로 사용합니다. 특정 리소스를 식별할 때 씁니다.

@GetMapping("/{id}")
public PostResponse getPost(@PathVariable Long id) {
    return postService.getPost(id);
}

요청: GET /api/posts/42

스프링이 하는 일:

  1. URL에서 {id} 자리에 있는 42를 꺼냄
  2. Long 타입으로 변환
  3. 메서드 파라미터 id42L을 넣어줌

변수 이름이 다를 때

URL의 변수명과 파라미터명이 다르면 직접 지정합니다:

@GetMapping("/{postId}")
public PostResponse getPost(@PathVariable("postId") Long id) {
    // URL의 {postId}를 id 변수에 넣음
    return postService.getPost(id);
}

Path Variable 여러 개

// GET /api/posts/42/comments/7
@GetMapping("/{postId}/comments/{commentId}")
public CommentResponse getComment(@PathVariable Long postId,
                                   @PathVariable Long commentId) {
    return commentService.getComment(postId, commentId);
}