From 13cce1a6c4ea8a6d82e6008d407ba1f91902d89b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 5 Aug 2024 23:38:52 -0700 Subject: [PATCH] Implement GiantBomb API with caching --- src/routes/api/giantbomb/+server.ts | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/routes/api/giantbomb/+server.ts diff --git a/src/routes/api/giantbomb/+server.ts b/src/routes/api/giantbomb/+server.ts new file mode 100644 index 0000000..f2a06d9 --- /dev/null +++ b/src/routes/api/giantbomb/+server.ts @@ -0,0 +1,49 @@ +import { promisify } from 'util' +import redis from '../redis-client' +import GiantBombAPI from 'giantbombing-api' + +import type { RequestHandler } from './$types' + +const CACHE_TTL = 60 * 60 * 24 * 7 + +const giantBombAPI = new GiantBombAPI({ + apiKey: process.env.GIANTBOMB_API_KEY, + userAgent: 'jedmund.com/1.0' +}) + +const getSearchAsync = promisify(giantBombAPI.getSearch.bind(giantBombAPI)) + +export const POST: RequestHandler = async ({ request }) => { + const { games } = await request.json() + const results = await Promise.all(games.map(getCachedOrFetchGame)) + return new Response(JSON.stringify(results)) +} + +async function getCachedOrFetchGame(game: SerializableGameInfo): Promise { + const cachedData = await redis.get(`giantbomb:${game.name}`) + if (cachedData) { + console.log(`Using cached data for Giant Bomb data about ${game.name}`) + return JSON.parse(cachedData) + } + + const options = { + query: game.name, + resources: 'game', + resource_type: 'game', + limit: 1 + } + + try { + const response = await getSearchAsync(options) + const revisedGame = { + ...game, + coverURL: response.results[0].image.medium_url + } + + await redis.setex(`giantbomb:${game.name}`, CACHE_TTL, JSON.stringify(revisedGame)) + return revisedGame + } catch (error) { + console.error(`Error fetching data for ${game.name}:`, error) + return game // Return original game if fetch fails + } +}