Skip to content

Best Practices

Tips for building great applications with ApiBiblia.

Caching

Cache Bible Content

Bible text doesn't change. Cache aggressively:

javascript
// Simple in-memory cache
const verseCache = new Map();

async function getVerse(ref, version = 'rvr60') {
  const key = `${version}:${ref}`;

  if (verseCache.has(key)) {
    return verseCache.get(key);
  }

  const data = await fetchFromApi(ref, version);
  verseCache.set(key, data);
  return data;
}

Use HTTP Caching

Our responses include cache headers. Configure your HTTP client to respect them:

javascript
// Using fetch with cache
const response = await fetch(url, {
  headers: { 'X-API-Key': apiKey },
  cache: 'default' // Respects Cache-Control headers
});

Cache Duration Recommendations

Content TypeSuggested TTL
Verses & Passages24 hours+
Book lists24 hours
Version lists1 hour
Search results5 minutes

Efficient API Usage

Batch Requests

Fetch ranges instead of individual verses:

javascript
// Instead of 3 requests
const v1 = await getPassage('Romans 8:28');
const v2 = await getPassage('Romans 8:29');
const v3 = await getPassage('Romans 8:30');

// Make 1 request
const verses = await getPassage('Romans 8:28-30');

Fetch Chapters, Not Verses

When displaying full chapters, use the chapters endpoint:

javascript
// Good: 1 request
const chapter = await fetch('/v1/chapters/psa_23');

// Bad: 6 requests
for (let i = 1; i <= 6; i++) {
  await fetch(`/v1/passage?ref=Psalm 23:${i}`);
}

Prefetch Content

Anticipate user actions and prefetch:

javascript
// User is viewing John 3, prefetch John 4
if (currentChapter === 'joh_3') {
  prefetch('/v1/chapters/joh_4');
}

Error Handling

Always Handle Errors

javascript
async function safeGetVerse(ref) {
  try {
    const response = await fetch(`/v1/passage?ref=${ref}`);
    const data = await response.json();

    if (!data.success) {
      console.error('API error:', data.error);
      return null;
    }

    return data.data;
  } catch (error) {
    console.error('Network error:', error);
    return null;
  }
}

Implement Retry Logic

javascript
async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);

      if (response.status === 429) {
        const wait = Math.pow(2, i) * 1000;
        await new Promise(r => setTimeout(r, wait));
        continue;
      }

      return response;
    } catch (error) {
      if (i === retries - 1) throw error;
    }
  }
}

Security

Keep API Keys Secret

Never expose API keys in client-side code:

javascript
// Bad: Key exposed in browser
fetch('/v1/verses/joh_3_16', {
  headers: { 'X-API-Key': 'ab_live_xxx' } // Visible to users!
});

// Good: Proxy through your backend
fetch('/api/verse/joh_3_16'); // Your server adds the API key

Use Environment Variables

bash
# .env (never commit this)
APIBIBLIA_API_KEY=ab_live_xxxxx
javascript
// server.js
const apiKey = process.env.APIBIBLIA_API_KEY;

User Experience

Show Loading States

javascript
function VerseDisplay({ reference }) {
  const [verse, setVerse] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    setLoading(true);
    getVerse(reference)
      .then(setVerse)
      .finally(() => setLoading(false));
  }, [reference]);

  if (loading) return <Skeleton />;
  return <VerseText verse={verse} />;
}

Handle Offline Gracefully

javascript
async function getVerseWithFallback(ref) {
  try {
    // Try network first
    const data = await fetchFromApi(ref);
    localStorage.setItem(`verse:${ref}`, JSON.stringify(data));
    return data;
  } catch (error) {
    // Fall back to cached version
    const cached = localStorage.getItem(`verse:${ref}`);
    if (cached) return JSON.parse(cached);
    throw error;
  }
}

Support Multiple Languages

Both Spanish and English book names work:

javascript
// These are equivalent
getPassage('John 3:16');
getPassage('Juan 3:16');

Monitoring

Track API Usage

javascript
let apiCalls = 0;

async function trackedFetch(url) {
  apiCalls++;
  console.log(`API call #${apiCalls}: ${url}`);
  return fetch(url);
}

Monitor Rate Limits

javascript
async function fetchAndMonitor(url) {
  const response = await fetch(url);

  const remaining = response.headers.get('X-RateLimit-Remaining');
  if (remaining < 10) {
    console.warn(`Low rate limit: ${remaining} requests remaining`);
  }

  return response;
}

Built on Cloudflare's global edge network.