pitstop / server.js
ardasen's picture
Update server.js
6f6e5ac verified
const express = require('express');
const axios = require('axios');
const NodeCache = require('node-cache');
const cron = require('node-cron');
const cors = require('cors');
const app = express();
const port = process.env.PORT || 7860;
const cache = new NodeCache(); // Remove stdTTL to prevent automatic expiration
const ERGAST_API_BASE_URL = 'https://ergast.com/api/f1/';
app.use(cors());
// Function to fetch data from Ergast API and update cache
const fetchDataAndUpdateCache = async (url, cacheKey) => {
try {
const response = await axios.get(url);
cache.set(cacheKey, response.data);
console.log(`Updated ${cacheKey} cache`);
} catch (error) {
console.error(`Error updating ${cacheKey} cache:`, error);
}
};
// Schedule to update cache every 15 minutes for all endpoints
//cron.schedule('*/15 * * * *', async () => {
cron.schedule('0 */12 * * *', async () => {
// Example: Update current season data
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}current.json`, 'currentSeason');
// Update driver standings for the current season
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}current/driverStandings.json`, 'driverStandings-current');
// Update driver standings for the current season
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}2024/driverStandings.json`, 'driverStandings-2024');
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}2024/driverStandings.json`, 'driverStandings');
// Update constructor standings for the current season
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}current/constructorStandings.json`, 'constructorStandings-current');
// Update constructor standings for the current season
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}2024/constructorStandings.json`, 'constructorStandings-2024');
await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}2024/constructorStandings.json`, 'constructorStandings');
// Update race results for 2024 season, rounds 1 to 24
// for (let round = 1; round <= 24; round++) {
// await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}current/${round}/results.json`, `raceResults-2024-${round}`);
// }
// Update additional endpoints as needed
// await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}current/other.json`, 'otherData');
// await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}seasons.json`, 'seasons');
//await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}drivers.json`, 'drivers');
// await fetchDataAndUpdateCache(`${ERGAST_API_BASE_URL}constructors.json`, 'constructors');
// Add more endpoints to update cache as needed
});
// Generic endpoint handler to fetch data with caching and error handling
const handleEndpointWithCache = async (req, res, url, cacheKey) => {
try {
const cachedData = cache.get(cacheKey);
if (cachedData) {
res.json(cachedData);
} else {
const response = await axios.get(url);
cache.set(cacheKey, response.data);
res.json(response.data);
}
} catch (error) {
console.error(`Error fetching ${cacheKey} from Ergast API:`, error);
const cachedData = cache.get(cacheKey);
if (cachedData) {
res.json(cachedData);
} else {
res.status(500).send(`Error fetching data from Ergast API for ${cacheKey} and no cache available.`);
}
}
};
// Endpoint to manually trigger cache update
app.get('/api/updateCache', async (req, res) => {
const { url, cacheKey } = req.query;
if (!url || !cacheKey) {
return res.status(400).send('url and cacheKey query parameters are required.');
}
try {
await fetchDataAndUpdateCache(url, cacheKey);
res.send(`Cache for ${cacheKey} updated successfully.`);
} catch (error) {
res.status(500).send(`Error updating cache for ${cacheKey}.`);
}
});
// Example endpoint to get current season data
app.get('/api/currentSeason', async (req, res) => {
await handleEndpointWithCache(req, res, `${ERGAST_API_BASE_URL}current.json`, 'currentSeason');
});
// Example endpoint to get driver standings data
app.get('/api/driverStandings', async (req, res) => {
const season = req.query.season || 'current';
await handleEndpointWithCache(req, res, `${ERGAST_API_BASE_URL}${season}/driverStandings.json`, `driverStandings-${season}`);
});
// Example endpoint to get constructor standings data
app.get('/api/constructorStandings', async (req, res) => {
const season = req.query.season || 'current';
await handleEndpointWithCache(req, res, `${ERGAST_API_BASE_URL}${season}/constructorStandings.json`, `constructorStandings-${season}`);
});
// Example endpoint to get race results data
app.get('/api/raceResults', async (req, res) => {
const season = req.query.season || 'current';
const round = req.query.round;
if (!round) {
return res.status(400).send('Round is required.');
}
await handleEndpointWithCache(req, res, `${ERGAST_API_BASE_URL}${season}/${round}/results.json`, `raceResults-${season}-${round}`);
});
// Add more endpoints with similar structure as needed
// Start server
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});