diff --git a/index.js b/index.js index 6e68f7a..3746176 100644 --- a/index.js +++ b/index.js @@ -5,99 +5,91 @@ const cors = require('cors'); const { param, validationResult } = require('express-validator'); const app = express(); +// Redis setup const redisConfig = { - url: process.env.REDIS_URL, - db: 1, + url: process.env.REDIS_URL, + database: 1, } -const client = redis.createClient(redisConfig); +let redisClient; -client.on('error', (err) => { - console.log(err); -}); +(async () => { + redisClient = redis.createClient(redisConfig); + redisClient.on("error", (error) => console.error(`Error: ${error}`)); + await redisClient.connect(); +})(); // CORS app.use(cors()); -function LeagueSeason(leagueID, year) { - this.params = { league: leagueID, season: year } +// Functions + +// Legacy fetch function +function LeagueSeason(league, season) { + this.url = 'https://api-football-v1.p.rapidapi.com/v3/standings'; + this.method = 'GET'; + this.params = { + league: league, + season: season, + }; this.headers = { - 'x-rapidapi-host': process.env.API_HOST, - 'x-rapidapi-key': process.env.API_KEY, + 'X-RapidAPI-Host': process.env.API_HOST, + 'X-RapidAPI-Key': process.env.API_KEY, + } +} + +// Fetch table from remote API +async function fetchTable(league, season) { + reqSeason = new LeagueSeason(league, season); + const apiResponse = await axios.request(reqSeason); + return apiResponse.data; +} + +// Get a league table +async function getLeagueTable(req, res) { + const league = req.params.league; + const season = req.params.season; + const seasontable = req.params.league + req.params.season; + let results; + let isCached = false; + + // Try to fetch a league table + try { + // First check cache + const cacheResults = await redisClient.get(seasontable); + if (cacheResults) { + isCached = true; + results = JSON.parse(cacheResults); + } else { + // Fetch remotely + results = await fetchTable(league, season); + if (results.length === 0) { + throw "API returned no data" + } + // Store table in cache + await redisClient.set(seasontable, JSON.stringify(results), { + EX: 21600, + NX: true, + }); + } + // Return the league table for the corresponding season + res.status(200).send({ + fromCache: isCached, + table: results + }); + } catch (error) { + console.error(error); + res.status(404).send("Data not found"); } } // Routes +// new method +app.get('/league/:league/:season', getLeagueTable); -app.get('/pl', async (req, res) => { - const league = '39'; - const year = '2021'; - const query = league + year; - try { - client.get(query, async (err, leagueTable) => { - if (err) throw err; +// Current Premier League Table +app.get('/pl', getLeagueTable); - // Return cached league table if present - if (leagueTable) { - res.status(200).send({ - table: JSON.parse(leagueTable), - message: 'data retrieved from cache', - }); - } else { - // Fetch from the API - reqSeason = new LeagueSeason(league, year); - const leagueTable = await axios.get( - 'https://v3.football.api-sports.io/standings', - reqSeason - ); - // Save result to cache - client.setex(query, 43200, JSON.stringify(leagueTable.data)); - // Return data from API - res.status(200).send({ - table: leagueTable.data, - message: 'cache miss', - }); - } - }); - } catch (err) { - res.status(500).send({ message: err.message }); - } -}); - -app.get('/championship', async (req, res) => { - const league = '40'; - const year = '2021'; - const query = league + year; - try { - client.get(query, async (err, leagueTable) => { - if (err) throw err; - - // Return cached league table if present - if (leagueTable) { - res.status(200).send({ - table: JSON.parse(leagueTable), - message: 'data retrieved from cache', - }); - } else { - // Fetch from the API - reqSeason = new LeagueSeason(league, year); - const leagueTable = await axios.get( - 'https://v3.football.api-sports.io/standings', - reqSeason - ); - // Save result to cache - client.setex(league, 43200, JSON.stringify(leagueTable.data)); - // Return data from API - res.status(200).send({ - table: leagueTable.data, - message: 'cache miss', - }); - } - }); - } catch (err) { - res.status(500).send({ message: err.message }); - } -}); app.get('/v2/:league/:year', [