Show HN: Librario, Google Books, ISBNDB 등을 통합하는 도서 메타데이터 API
요약
Librario는 Google Books, ISBNDB 등 여러 소스의 도서 데이터를 통합하여 제공하는 Go 기반의 메타데이터 API입니다. 필드별 점수 산정 시스템과 우선순위 전략을 통해 데이터 충돌을 해결하고 최적의 도서 정보를 병합합니다.
핵심 포인트
- 여러 도서 데이터 소스를 하나의 API로 통합
- Go 언어와 PostgreSQL을 사용한 데이터 병합 및 저장
- 제목 및 표지 품질을 위한 필드별 점수 산정 시스템 적용
- 캐싱 레이어 도입을 통한 응답 속도 향상
요약(TLDR): Librario는 Google Books, ISBNDB, Hardcover의 데이터를 하나의 응답으로 통합하는 도서 메타데이터 API로, 단일 소스에서 완전한 도서 정보를 얻을 수 없는 문제를 해결합니다. 현재 프리 알파(pre-alpha) 단계이며, AGPL 라이선스를 따르고 지금 바로 사용해 볼 수 있습니다0.
제 아내와 저는 약 1,800권의 책이 있는 개인 서재를 가지고 있습니다. 저희를 위한 도서 관리 도구를 만들기 시작했지만, 도서 정보에 대한 데이터 소스가 필요하다는 것을 금방 깨달았고, 기존의 솔루션 중 그 어떤 것도 제가 필요로 하는 모든 데이터를 제공하지 않았습니다. 어떤 것은 시리즈 정보를 제공하고, 다른 것은 장르를 제공하며, 또 다른 것은 좋은 표지 이미지를 제공할 수는 있지만, 모든 것을 제공하는 곳은 없었습니다.
그래서 저는 Go 언어로 작성된 도서 메타데이터 통합 API인 Librario를 만들기 시작했습니다. 이 API는 여러 소스(Google Books, ISBNDB, Hardcover. 다음으로는 Goodreads와 Anna's Archive 작업 예정)로부터 도서 정보를 가져와서, 모든 것을 병합하고, 향후 조회를 위해 PostgreSQL 데이터베이스에 저장합니다. 더 많은 도서가 조회됨에 따라 데이터베이스가 시간이 지남에 따라 점점 더 강력해지는 것이 핵심 아이디어입니다.
여기서 응답 예시1를 확인하거나 직접 시도해 볼 수 있습니다:
curl -s -H 'Authorization: Bearer librario_ARbmrp1fjBpDywzhvrQcByA4sZ9pn7D5HEk0kmS34eqRcaujyt0enCZ' \
'https://api.librario.dev/v1/book/9781328879943' | jq .
이 프로젝트는 프리 알파(pre-alpha) 단계이며 작은 VPS에서 실행되고 있으므로 이 점을 유의해 주세요. 저는 아직 제3자 서비스의 제한(limits)에 도달한 적이 없으므로, 이 게시물의 반응에 따라 코드가 이를 잘 처리하는지 알게 될 수도 있고 그렇지 못할 수도 있습니다.
병합(merger)은 이 서비스의 핵심이며, 서로 다른 소스에서 오는 충돌하는 데이터를 어떻게 결합할지 결정하는 것이 가장 어려운 부분이었습니다. 결국 저는 다소 단순하지만 현재로서는 작동하는 필드별 특정 전략(field-specific strategies)을 사용하기로 결정했습니다.
각 추출기(extractor)에는 우선순위가 있으며, 결과는 병합하기 전에 해당 우선순위에 따라 정렬됩니다. 하지만 우선순위만으로는 충분하지 않기 때문에, 서로 다른 필드에는 서로 다른 처리가 필요합니다.
예를 들어:
-
제목 (Titles)은 점수 산정 시스템 (scoring system)을 사용합니다. 소스에서 때때로 부제를 메인 제목 필드에 밀어넣는 경우가 있기 때문에, 괄호나 대괄호가 포함된 제목에는 감점을 부여합니다. 또한 너무 긴 제목 (80자 이상)도 감점 대상인데, 이는 종종 다른 곳에 있어야 할 판본 정보나 기타 메타데이터를 포함하고 있기 때문입니다.
-
표지 (Covers)는 모든 후보 URL을 수집한 다음, 별도의 페처 (fetcher)가 이를 다운로드하여 크기 (dimensions)와 품질 (quality)에 따라 점수를 매깁니다. 가장 좋은 것이 로컬에 저장되어 서버에서 제공됩니다.
그 외 대부분의 필드 (출판사, 언어, 페이지 수)에 대해서는 우선순위에 따라 비어 있지 않은 첫 번째 값을 가져옵니다. 단순하지만 효과적입니다.
최근에 캐싱 레이어 (caching layer) 2를 추가하여 속도가 상당히 향상되었습니다. 한때 net/http에서 fiber로 마이그레이션 (migrating) 3하는 것을 고려하기도 했지만, 하지 않기로 결정했습니다. 표준 라이브러리 (standard library)를 벗어나는 것이 맞지 않다고 느껴졌고, 결과적으로 마이그레이션이 큰 이득을 주지 못했기 때문입니다.
데이터베이스 레이어 (database layer)는 v1.0 4 이전에 재작성될 예정입니다. 솔직히 말씀드리면, 원래 스키마 (schema)는 AI가 작성했습니다. SQLC 5와 잘 작성된 문서를 통해 올바른 방향으로 유도하려고 노력했지만, 데이터베이스 설계는 제 강점이 아니며 작성된 코드를 자신 있게 보증할 수 없었습니다. 제가 완전히 이해하지 못하는 것을 출시하기보다는, SourceHut 6의 개발자들을 고용하여 제대로 재작성하도록 했습니다.
이제 5개월 된 아기가 있어서 아직 아이의 스케줄에 적응 중이라 개발 속도가 느립니다. 이전에 몇몇 HN 스레드 7에서 이 프로젝트를 언급한 적이 있는데, 마침내 사람들이 직접 시도해 볼 수 있는 결과물을 내놓게 되어 매우 기쁩니다.
코드는 AGPL 라이선스이며 SourceHut 8에 있습니다.
피드백과 패치 (patches) 9는 언제나 환영합니다 :)
AI 자동 생성 콘텐츠
본 콘텐츠는 HN Design Systems의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기