이번 편의 목표: 주소에 포함된 번호와 물음표 뒤의 검색어를 메서드 매개변수로 받습니다.

조회 조건을 메서드 안에 적어 두면 책을 바꿀 때마다 코드를 수정해야 합니다. 요청 주소에서 값을 받습니다.

경로 변수와 요청 매개변수

Book.java를 추가합니다. record는 필드를 한 번 적으면 생성자와 조회 메서드가 만들어지는 데이터 클래스입니다. book.title()처럼 필드 이름으로 값을 읽습니다.

Java
package com.thinktree.library;

public record Book(Long id, String title, int price) {
}

BookController를 다음 내용으로 바꿉니다. 아직 저장소가 없으므로 요청이 연결되는지만 확인하는 응답입니다. 05편의 /count 연습은 넣지 않습니다. count라는 글자도 /{id}와 겹치면 숫자 변환에 실패할 수 있습니다.

Java
package com.thinktree.library;

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

@RestController
@RequestMapping("/api/books")
public class BookController {
    @GetMapping("/{id}")
    public Book find(@PathVariable Long id) {
        return new Book(id, "샘플", 0);
    }

    @GetMapping
    public String search(@RequestParam(defaultValue = "") String title) {
        if (title.isBlank()) {
            return "전체 목록";
        }
        return "제목 검색: " + title;
    }
}

GET /api/books/7 은 id가 7인 Book JSON으로 응답합니다. 브라우저에는 id, title, price가 보입니다. GET /api/books 는 전체 목록이라는 글이, GET /api/books?title=개미 는 제목 검색: 개미가 반환됩니다.

경로의 {id}와 @PathVariable 이름이 같으면 연결됩니다. @RequestParam은 쿼리 문자열입니다. defaultValue를 두면 title 없이 호출해도 메서드가 실행됩니다. 개수는 나중에 목록 크기로 계산합니다.

직접 해 보기

GET /api/books/3 을 호출해 응답의 id가 3인지 확인하세요. 이어서 /api/books?title=자바 의 응답 문장도 확인하세요.

해설

경로 변수 3은 Long id로 변환되어 Book의 id가 됩니다. 쿼리의 자바는 title 매개변수로 들어갑니다. 숫자가 아닌 /api/books/abc 는 변환에 실패해 400대 오류가 됩니다.