-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
작가 검색 API 구현 완료
구현 개요
- Endpoint:
GET /api/v1/search/authors - 기능: 검색어에 해당하는 작가 목록과 각 작가의 대표작(최대 2권)을 조회
- 사용 위치: 검색 화면의 '작가' 탭
주요 특징
1. N+1 문제 해결
- 2단계 조회 전략 적용
- 작가 목록 조회 (페이징)
- 작가별 도서 카운트 조회 (GROUP BY)
- 작가별 도서 목록 조회 (IN 쿼리)
- 총 3개의 쿼리로 모든 데이터 조회
@EntityGraph보다 효율적이고 유지보수 용이
2. 페이징 지원
- 클라이언트 요청에 따라 페이지 단위로 조회
- 무한 스크롤 UI 지원
- 최대 페이지 크기: 50
3. 대표작 자동 선정
- 각 작가당 최대 2권의 대표작 표시
- 최신 출판일 기준으로 정렬
- UI 공간 효율성 확보
4. 역할 기반 필터링
BookAuthors.role = AUTHOR만 조회- 번역가(
TRANSLATOR)는 제외 - 정확한 작가 정보 제공
API 명세
Request
GET /api/v1/search/authors?query={검색어}&page={페이지}&size={크기}| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | String | O | - | 검색 키워드 (작가명) |
| page | int | X | 1 | 페이지 번호 (1부터 시작) |
| size | int | X | 10 | 페이지 크기 (최대 50) |
Response
{
"page": 1,
"size": 10,
"isEnd": true,
"totalCount": 1,
"items": [
{
"authorId": 42,
"name": "김영하",
"profileImageUrl": "https://example.com/authors/kim-younha.jpg",
"occupation": "소설가",
"nationality": "한국",
"bio": "1968년생 한국 소설가...",
"bookCount": 15,
"books": [
{
"bookId": 1234,
"title": "살인자의 기억법",
"thumbnailUrl": "https://example.com/books/1234.jpg",
"authorNames": ["김영하"],
"publisherName": "문학동네",
"publishedAt": "2013-07-15T00:00:00"
},
{
"bookId": 5678,
"title": "빛의 제국",
"thumbnailUrl": "https://example.com/books/5678.jpg",
"authorNames": ["김영하"],
"publisherName": "문학동네",
"publishedAt": "2006-11-20T00:00:00"
}
]
}
]
}예외 처리
1. 검색 결과 없음
{
"page": 1,
"size": 10,
"isEnd": true,
"totalCount": 0,
"items": []
}- 빈 배열 반환 (404 아님)
- 프론트엔드에서 "검색 결과가 없습니다" UI 표시
2. 잘못된 입력값
// 빈 검색어
GET /api/v1/search/authors?query=
→ 400 Bad Request: "검색 키워드는 필수입니다."
// 잘못된 페이지 번호
GET /api/v1/search/authors?query=김영하&page=0
→ 400 Bad Request: "페이지 번호는 1 이상이어야 합니다."
// 페이지 크기 초과
GET /api/v1/search/authors?query=김영하&size=100
→ 400 Bad Request: "페이지 크기는 1~50 사이여야 합니다."3. 작가는 있지만 도서가 없는 경우
{
"authorId": 99,
"name": "신인작가",
"bookCount": 0,
"books": []
}- 정상 응답
- UI에서 "등록된 작품이 없습니다" 표시
성능 임계값
- 작가 수 < 1,000: 현재 전략으로 충분 (응답 시간 < 100ms)
- 작가 수 1,000~10,000: 인덱스 튜닝 필요
- 작가 수 > 10,000: Elasticsearch 도입 검토
향후 최적화 예정 후보 목록
-
캐싱 전략
- Redis에 인기 작가 캐싱 (TTL 1시간)
- 검색 결과 캐싱 (TTL 10분)
-
Full-Text Search
- MySQL Full-Text Index 적용
- 또는 Elasticsearch 도입
- 한글 형태소 분석기 추가
-
비동기 처리
- 도서 카운트는 비동기로 조회
- CompletableFuture 활용
주의사항
1. 동명이인 문제
- 현재 ERD는
authors.name에 UNIQUE 제약이 있음 - "김영하(소설가)"와 "김영하(시인)"을 구분 불가
- 단기 해결:
shortIntro또는bio에 구분 정보 포함 - 장기 해결: UNIQUE 제약 제거 또는
name_disambiguation컬럼 추가
2. 부분 검색 성능
- 현재:
LIKE '%keyword%'(전체 검색) - 문제: 인덱스를 활용하지 못함
- 대안:
LIKE 'keyword%'(접두사 검색) 또는 Full-Text Search
3. bio 길이 제한
- DB:
LONGTEXT(제한 없음) - API: 200자로 자르고 "..." 추가
- 상세 페이지에서 전체 내용 제공 필요
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request