ISBNdb Integration
ISBNdb is a comprehensive book metadata database. BookWish uses ISBNdb to look up detailed book information by ISBN, search by title/author, and retrieve publisher data.
Overview
BookWish uses ISBNdb for:
- ISBN Lookup: Get book details by ISBN
- Title Search: Search books by title
- Author Search: Find books by author name
- Metadata Enrichment: Publisher, page count, categories, descriptions
- Cover Images: Book cover artwork URLs
- MSRP Data: Publisher's suggested retail prices
Implementation
Location: /backend/src/integrations/isbndb.ts
Configuration
Required environment variables:
ISBNDB_API_KEY=your_api_key
The integration uses Redis for caching with 24-hour TTL.
Features
1. ISBN Lookup
Get comprehensive book data by ISBN-10 or ISBN-13.
Get Book by ISBN
import { createISBNdbClient } from '../integrations/isbndb';
const isbndb = createISBNdbClient(process.env.ISBNDB_API_KEY);
const book = await isbndb.getBookByISBN('9780743273565');
// Returns:
// {
// isbndbId: '9780743273565',
// isbn13: '9780743273565',
// isbn10: '0743273565',
// title: 'The Great Gatsby',
// subtitle: undefined,
// authors: ['F. Scott Fitzgerald'],
// publisher: 'Scribner',
// publishedDate: Date('2004-05-01'),
// description: 'The exemplary novel of the Jazz Age...',
// pageCount: 180,
// categories: ['Fiction', 'Classics', 'Literature'],
// coverImageUrl: 'https://images.isbndb.com/covers/...',
// thumbnailUrl: 'https://images.isbndb.com/covers/...',
// msrp: 1599 // $15.99 in cents
// }
Supports both ISBN formats:
- ISBN-13:
9780743273565 - ISBN-10:
0743273565 - With dashes:
978-0-7432-7356-5
2. Search Books
Search for books by title or general query.
Search by Title
const results = await isbndb.searchBooks('Great Gatsby', 1, 20);
// Returns array of BookData objects
// page: 1, pageSize: 20
Pagination
// First page
const page1 = await isbndb.searchBooks('Harry Potter', 1, 20);
// Second page
const page2 = await isbndb.searchBooks('Harry Potter', 2, 20);
3. Author Search
Find all books by a specific author.
Get Books by Author
const books = await isbndb.getBooksByAuthor('F. Scott Fitzgerald', 1, 20);
// Returns:
// [
// { title: 'The Great Gatsby', ... },
// { title: 'Tender Is the Night', ... },
// { title: 'This Side of Paradise', ... },
// // ... more books
// ]
Data Structures
BookData
interface BookData {
isbndbId?: string; // ISBNdb internal ID
isbn13?: string; // ISBN-13
isbn10?: string; // ISBN-10
title: string; // Book title
subtitle?: string; // Subtitle if present
authors: string[]; // Array of author names
publisher?: string; // Publisher name
publishedDate?: Date; // Publication date
description?: string; // Book description/overview
pageCount?: number; // Number of pages
categories: string[]; // Subject categories
coverImageUrl?: string; // Full-size cover image
thumbnailUrl?: string; // Thumbnail cover image
msrp?: number; // Retail price in cents
}
ISBNdb API Response Format
Raw ISBNdb API returns:
interface ISBNdbBook {
title: string;
title_long?: string;
isbn?: string;
isbn13?: string;
dewey_decimal?: string;
binding?: string; // 'Paperback', 'Hardcover'
publisher?: string;
language?: string;
date_published?: string;
edition?: string;
pages?: number;
dimensions?: string;
overview?: string; // Description
image?: string; // Cover URL
msrp?: number; // Price in dollars
authors?: string[];
subjects?: string[]; // Categories
}
Caching Strategy
Cache Configuration
private cachePrefix = 'isbndb:';
private cacheTTL = 24 * 60 * 60; // 24 hours
Cache Keys
- ISBN lookup:
isbndb:isbn:{isbn} - Title search:
isbndb:search:{query}:{page}:{pageSize} - Author search:
isbndb:author:{name}:{page}:{pageSize}
Cache Implementation
// Check cache
const cacheKey = `${this.cachePrefix}isbn:${isbn}`;
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Fetch from API
const book = await fetchFromISBNdb(isbn);
// Cache result
await redis.setex(cacheKey, this.cacheTTL, JSON.stringify(book));
API Details
Base URL
https://api2.isbndb.com
Authentication
Header-based authentication:
Authorization: {ISBNDB_API_KEY}
Endpoints
Get Book by ISBN
GET /book/{isbn}
Search Books
GET /books/{query}?page={page}&pageSize={pageSize}
Search by Author
GET /author/{authorName}?page={page}&pageSize={pageSize}
Error Handling
Rate Limiting
ISBNdb has rate limits based on subscription tier:
try {
const book = await isbndb.getBookByISBN(isbn);
} catch (error) {
if (error.message === 'Rate limit exceeded for ISBNdb API') {
// Wait and retry, or serve from cache
}
}
Not Found
const book = await isbndb.getBookByISBN('invalid-isbn');
// Returns null (not an error)
Network Errors
try {
const results = await isbndb.searchBooks(query);
} catch (error) {
// Log error and fall back to cached data or Google Books
}
Data Transformation
The integration transforms ISBNdb responses to BookWish format:
Date Parsing
let publishedDate: Date | undefined;
if (book.date_published) {
try {
publishedDate = new Date(book.date_published);
} catch {
// Invalid date format, leave undefined
}
}
Price Conversion
// ISBNdb returns dollars, convert to cents
let msrp: number | undefined;
if (book.msrp) {
msrp = Math.round(book.msrp * 100);
}
Description Handling
// Use overview or synopsys
const description = book.overview || book.synopsys;
Integration with Book Service
Example usage in book service:
import { createISBNdbClient } from '../integrations/isbndb';
import { createGoogleBooksClient } from '../integrations/google-books';
async function lookupBook(isbn: string) {
const isbndb = createISBNdbClient(process.env.ISBNDB_API_KEY);
// Try ISBNdb first
let book = await isbndb.getBookByISBN(isbn);
if (!book) {
// Fallback to Google Books
const googleBooks = createGoogleBooksClient(process.env.GOOGLE_BOOKS_API_KEY);
book = await googleBooks.getBookByISBN(isbn);
}
if (!book) {
throw new Error('Book not found');
}
// Store in database
return await createBook(book);
}
Best Practices
- Cache Aggressively: Book metadata rarely changes, use 24h+ cache
- Fallback to Google Books: Use Google Books as secondary source
- Normalize ISBNs: Remove dashes before lookup
- Handle Missing Data: Not all fields present for all books
- Monitor Rate Limits: Track API usage against plan limits
- Batch Queries: Avoid sequential lookups, use Promise.all when possible
- Error Recovery: Gracefully handle API downtime
Rate Limits
ISBNdb rate limits by plan tier:
| Plan | Requests/Day | Requests/Second |
|---|---|---|
| Free | 1,000 | N/A |
| Developer | 10,000 | N/A |
| Pro | 100,000 | N/A |
| Enterprise | Unlimited | 10/sec |
Use Cases
1. Book Discovery
When user scans ISBN:
async function scanISBN(isbn: string) {
const isbndb = createISBNdbClient(process.env.ISBNDB_API_KEY);
const book = await isbndb.getBookByISBN(isbn);
if (book) {
// Display book info to user
return book;
} else {
return { error: 'Book not found' };
}
}
2. Inventory Creation
When adding books to store inventory:
async function addToInventory(isbn: string, quantity: number) {
const book = await isbndb.getBookByISBN(isbn);
if (!book) {
throw new Error('Book metadata not found');
}
return await createInventoryItem({
isbn,
title: book.title,
authors: book.authors,
quantity,
priceCents: book.msrp || 0,
coverUrl: book.coverImageUrl
});
}
3. Search Results
Power book search:
async function searchBooks(query: string, page: number = 1) {
const results = await isbndb.searchBooks(query, page, 20);
return {
books: results,
page,
hasMore: results.length === 20
};
}
Limitations
- Coverage: Not all books in database (especially very old or obscure)
- International: Primarily English-language books
- Images: Cover images may be low quality or missing
- Rate Limits: Based on subscription plan
- Accuracy: Data quality varies by publisher
- Updates: Metadata may be outdated for some titles
Comparison with Google Books
ISBNdb Advantages
- More comprehensive ISBN database
- Better metadata completeness
- Includes MSRP data
- Higher rate limits (paid plans)
Google Books Advantages
- Free with no rate limits (within quota)
- Better cover images
- More international coverage
- Preview pages available
Recommended Strategy
Use both in combination:
- Try ISBNdb first (more complete ISBN coverage)
- Fallback to Google Books if not found
- Use Google Books for cover images if ISBNdb's are low quality
Testing
Mock Data
For testing without API key:
const mockBook: BookData = {
isbndbId: '9780743273565',
isbn13: '9780743273565',
isbn10: '0743273565',
title: 'The Great Gatsby',
authors: ['F. Scott Fitzgerald'],
publisher: 'Scribner',
publishedDate: new Date('2004-05-01'),
description: 'A classic novel...',
pageCount: 180,
categories: ['Fiction', 'Classics'],
coverImageUrl: 'https://example.com/cover.jpg',
msrp: 1599
};
Test ISBNs
Known ISBNs for testing:
9780743273565- The Great Gatsby9780142437247- The Giver9780061120084- To Kill a Mockingbird