Best Practices
Follow these best practices to get the most out of Mumin API.
Authentication
Secure Your API Keys
⚠️
Never commit API keys to version control or expose them in client-side code.
✅ Good:
// Use environment variables
const apiKey = process.env.MUMIN_API_KEY❌ Bad:
// Don't hardcode keys
const apiKey = 'sk_mumin_abc123...'Rotate Keys Regularly
Rotate your API keys every 90 days for security.
Rate Limiting
Implement Exponential Backoff
javascript✨ Live Editor
Monitor Rate Limits
const response = await fetch('...')
const remaining = response.headers.get('X-RateLimit-Remaining')
const reset = response.headers.get('X-RateLimit-Reset')
if (parseInt(remaining) < 10) {
console.warn('Rate limit almost exceeded!')
}Caching
Cache Responses
API responses are cached for 24 hours. Implement your own caching for better performance.
const cache = new Map()
async function getCachedHadith(id) {
if (cache.has(id)) {
return cache.get(id)
}
const hadith = await fetchHadith(id)
cache.set(id, hadith)
// Expire after 1 hour
setTimeout(() => cache.delete(id), 3600000)
return hadith
}Error Handling
Handle All Error Cases
try {
const hadith = await client.hadiths.get(id)
} catch (error) {
if (error.code === 'NOT_FOUND') {
// Handle missing hadith
} else if (error.code === 'RATE_LIMIT_EXCEEDED') {
// Wait and retry
} else if (error.code === 'BALANCE_DEPLETED') {
// Notify user to top up
} else {
// Log unexpected errors
console.error('Unexpected error:', error)
}
}Performance
Use Pagination
Don't fetch all hadiths at once. Use pagination:
async function getAllHadiths() {
const limit = 100
let offset = 0
const allHadiths = []
while (true) {
const response = await client.hadiths.list({ limit, offset })
allHadiths.push(...response.data)
if (response.data.length < limit) break
offset += limit
}
return allHadiths
}Request Only Needed Languages
// ✅ Good - only request needed languages
const hadith = await client.hadiths.get(1, { lang: 'en' })
// ❌ Bad - requesting all languages
const hadith = await client.hadiths.get(1, { lang: 'ar,en,ru,uz' })Security
Use HTTPS Only
Always use HTTPS in production:
const API_URL = process.env.NODE_ENV === 'production'
? 'https://api.mumin.ink/v1'
: 'http://localhost:3000/v1'Validate Input
function validateHadithId(id) {
const numId = parseInt(id)
if (isNaN(numId) || numId < 1 || numId > 7563) {
throw new Error('Invalid hadith ID')
}
return numId
}Monitoring
Log Request IDs
Always log requestId for debugging:
try {
const hadith = await client.hadiths.get(id)
} catch (error) {
console.error('Request failed:', {
requestId: error.requestId,
error: error.message
})
}Track Usage
Monitor your API usage:
let requestCount = 0
async function trackRequest(fn) {
requestCount++
console.log(`Total requests: ${requestCount}`)
return await fn()
}Cost Optimization
Batch Requests
Instead of making multiple requests, batch them:
// ✅ Good - batch requests
const hadiths = await Promise.all([
client.hadiths.get(1),
client.hadiths.get(2),
client.hadiths.get(3)
])
// ❌ Bad - sequential requests
const h1 = await client.hadiths.get(1)
const h2 = await client.hadiths.get(2)
const h3 = await client.hadiths.get(3)Use Search Wisely
Search is more expensive than direct access:
// ✅ Good - if you know the ID
const hadith = await client.hadiths.get(1)
// ❌ Bad - using search when ID is known
const results = await client.hadiths.search('hadith 1')