Skip to main content

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);

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

  1. Cache Aggressively: Book metadata rarely changes, use 24h+ cache
  2. Fallback to Google Books: Use Google Books as secondary source
  3. Normalize ISBNs: Remove dashes before lookup
  4. Handle Missing Data: Not all fields present for all books
  5. Monitor Rate Limits: Track API usage against plan limits
  6. Batch Queries: Avoid sequential lookups, use Promise.all when possible
  7. Error Recovery: Gracefully handle API downtime

Rate Limits

ISBNdb rate limits by plan tier:

PlanRequests/DayRequests/Second
Free1,000N/A
Developer10,000N/A
Pro100,000N/A
EnterpriseUnlimited10/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

Use both in combination:

  1. Try ISBNdb first (more complete ISBN coverage)
  2. Fallback to Google Books if not found
  3. 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 Gatsby
  • 9780142437247 - The Giver
  • 9780061120084 - To Kill a Mockingbird

Additional Resources