All API calls in the DBA Agent frontend now use the centralized API client located at src/lib/api/client.js. This provides:
- ✅ Centralized configuration - Single place to update API URLs
- ✅ Consistent error handling - Unified error messages
- ✅ Environment support - Automatic dev/prod URL switching
- ✅ Request/Response interceptors - Easy to add auth, logging, etc.
- ✅ Type safety - Clear API method signatures
import { connectionAPI, playbookAPI, advisorAPI } from '@/lib/api/client'// ❌ OLD WAY (Don't do this)
const response = await fetch('http://localhost:8080/api/playbooks')
const data = await response.json()
// ✅ NEW WAY (Use this)
const data = await playbookAPI.getAllPlaybooks()await connectionAPI.testConnection(connectionData)
await connectionAPI.saveConnection(connectionData)
await connectionAPI.getAllConnections()
await connectionAPI.deleteConnection(connectionId)
await connectionAPI.updateConnection(connectionId, data)await schemaAPI.scanSchema(connectionId)
await schemaAPI.getSchema(connectionId)
await schemaAPI.getVisualization(connectionId)await statsAPI.getStats(connectionId)await queryAPI.getDatabaseObjects(connectionId)
await queryAPI.executeQuery(connectionId, query, limit)
await queryAPI.getTableIndexes(connectionId, tableName)await chatAPI.sendMessage(connectionId, message, threadId)await advisorAPI.analyzeDatabase(connectionId)await slowQueriesAPI.getHistory(connectionId)
await slowQueriesAPI.saveExplainPlan(data)
await slowQueriesAPI.deleteHistory(id)await indexAPI.getRecommendations(connectionId)
await indexAPI.generateRecommendations(connectionId)
await indexAPI.applyRecommendation(id)
await indexAPI.dismissRecommendation(id)
await indexAPI.deleteRecommendation(id)await performanceAPI.getPerformanceMetrics(connectionId)
await performanceAPI.getDashboardData(connectionId, days)await lockAPI.getActiveLocks(connectionId)
await lockAPI.getStatistics(connectionId)
await lockAPI.detectContentions(connectionId)
await lockAPI.killSession(connectionId, pid)await activeQueriesAPI.getActiveQueries(connectionId)
await activeQueriesAPI.getLatestQueries(connectionId)
await activeQueriesAPI.getStatistics(connectionId)
await activeQueriesAPI.getFilterOptions(connectionId)
await activeQueriesAPI.captureQueries(connectionId)
await activeQueriesAPI.killQuery(connectionId, pid)await configAPI.getConfiguration(connectionId)
await configAPI.analyzeConfiguration(connectionId)
await configAPI.updateConfiguration(connectionId, settings)await explainAPI.getHistory(connectionId)
await explainAPI.analyzeQuery(connectionId, query, useAnalyze)
await explainAPI.saveHistory(data)
await explainAPI.deleteHistory(id)// Get playbooks
await playbookAPI.getAllPlaybooks(params)
await playbookAPI.getPlaybook(playbookId)
// Manage playbooks
await playbookAPI.createPlaybook(data)
await playbookAPI.updatePlaybook(playbookId, data)
await playbookAPI.deletePlaybook(playbookId)
await playbookAPI.togglePlaybook(playbookId)
// Execute and monitor
await playbookAPI.executePlaybook(playbookId, connectionId)
await playbookAPI.getRunHistory(connectionId, limit)
await playbookAPI.cancelRun(runId)
// Alerts
await playbookAPI.getAlerts(connectionId, unacknowledgedOnly)
await playbookAPI.acknowledgeAlert(alertId, acknowledgedBy)The API client automatically handles errors:
try {
const data = await playbookAPI.getAllPlaybooks()
// Use data
} catch (error) {
// Error is already formatted with a clear message
console.error('Error:', error.message)
// Show to user: error.message
}The API client automatically uses the correct URL:
- Development:
http://localhost:8080 - Production: your deployment's API base URL (set
VITE_API_URL) - Custom: Set
NEXT_PUBLIC_API_URLenvironment variable
All components have been successfully migrated to use the centralized API client:
✅ PlaybooksTab.js - Uses playbookAPI
✅ ConfigurationTunerTab.js - Uses configAPI
✅ LockContentionTab.js - Uses lockAPI
✅ PerformanceDashboard.js - Uses performanceAPI
✅ IndexRecommendationsTab.js - Uses indexAPI
✅ DatabaseAdvisorTab.js - Uses advisorAPI
✅ SlowQueryAnalysisTab.js - Uses slowQueriesAPI
✅ ActiveQueryTab.js - Uses activeQueriesAPI
✅ ExplainPlanTab.js - Uses explainAPI
-
Import the appropriate API:
import { advisorAPI } from '@/lib/api/client'
-
Replace fetch calls:
// Before const res = await fetch(`http://localhost:8080/api/advisor/analyze/${connectionId}`) const data = await res.json() // After const data = await advisorAPI.analyzeDatabase(connectionId)
-
Update error handling (errors are now thrown, not returned):
// Before if (data.success) { ... } else { ... } // After try { const data = await advisorAPI.analyzeDatabase(connectionId) // data is already the response } catch (error) { // Handle error }
const response = await fetch('http://localhost:8080/api/playbooks', {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
const data = await response.json()
if (!data.success) throw new Error(data.message)const data = await playbookAPI.getAllPlaybooks()Much cleaner! 🎉
To add a new API endpoint:
-
Add the method to the appropriate API object in
client.js:export const playbookAPI = { // ... existing methods newMethod: async (param) => { const response = await apiClient.get(`/api/playbooks/${param}`) return response.data } }
-
Use it in your component:
import { playbookAPI } from '@/lib/api/client' const data = await playbookAPI.newMethod(param)
To migrate a component to use the centralized API:
- Import the appropriate API from
@/lib/api/client - Replace
fetch()calls with API methods - Remove manual URL construction
- Remove manual header setting
- Update error handling
- Test the component
- All API methods return the
response.datadirectly (no need to call.json()) - Errors are thrown automatically (use try/catch)
- Base URL is configured automatically based on environment
- Timeout is set to 30 seconds by default
- All requests include
Content-Type: application/jsonheader