From 2bbdd1b844ef99e1eb52c35aecd298e1ccc3f1ae Mon Sep 17 00:00:00 2001 From: CS-parth Date: Tue, 6 May 2025 15:11:16 +0530 Subject: [PATCH] [Add][Done][Parth] : Added redis caching on more api endpoints --- langsuit/app/api/lessons/route.ts | 64 +++++++++++++++++++++++-------- langsuit/app/api/units/route.ts | 27 ++++++++++--- langsuit/lib/cache-utils.ts | 26 +++++++++++++ 3 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 langsuit/lib/cache-utils.ts diff --git a/langsuit/app/api/lessons/route.ts b/langsuit/app/api/lessons/route.ts index da369dd..4670266 100644 --- a/langsuit/app/api/lessons/route.ts +++ b/langsuit/app/api/lessons/route.ts @@ -3,6 +3,8 @@ import { type NextRequest, NextResponse } from "next/server"; import db from "@/db/drizzle"; import { lessons } from "@/db/schema"; import { getIsAdmin } from "@/lib/admin"; +import { getCachedResponse } from "@/lib/cache"; +import { invalidateCache } from "@/lib/cache-utils"; /** * @swagger @@ -59,27 +61,57 @@ import { getIsAdmin } from "@/lib/admin"; * description: Unauthorized - Admin access required */ -export const GET = async () => { - const isAdmin = getIsAdmin(); - if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 }); +export async function GET() { + try { + const isAdmin = await getIsAdmin(); + if (!isAdmin) { + return NextResponse.json( + { error: "Unauthorized - Admin access required" }, + { status: 401 }, + ); + } - const data = await db.query.lessons.findMany(); + const lessons = await getCachedResponse( + 'lessons', + async () => { + const result = await db.query.lessons.findMany(); + return result; + }, + 900 // 15 minutes cache + ); - return NextResponse.json(data); + return NextResponse.json(lessons); + } catch (error) { + console.error("Error fetching lessons:", error); + return NextResponse.json( + { error: "Failed to fetch lessons" }, + { status: 500 }, + ); + } }; -export const POST = async (req: NextRequest) => { - const isAdmin = getIsAdmin(); - if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 }); +export async function POST(req: NextRequest) { + try { + const isAdmin = await getIsAdmin(); + if (!isAdmin) { + return NextResponse.json( + { error: "Unauthorized - Admin access required" }, + { status: 401 }, + ); + } - const body = (await req.json()) as typeof lessons.$inferSelect; + const body = await req.json(); + const lesson = await db.insert(lessons).values(body).returning().get(); - const data = await db - .insert(lessons) - .values({ - ...body, - }) - .returning(); + // Invalidate cache for lessons + await invalidateCache('lessons'); - return NextResponse.json(data[0]); + return NextResponse.json(lesson); + } catch (error) { + console.error("Error creating lesson:", error); + return NextResponse.json( + { error: "Failed to create lesson" }, + { status: 500 }, + ); + } }; diff --git a/langsuit/app/api/units/route.ts b/langsuit/app/api/units/route.ts index 60b47c9..2fe0661 100644 --- a/langsuit/app/api/units/route.ts +++ b/langsuit/app/api/units/route.ts @@ -49,18 +49,35 @@ */ import { type NextRequest, NextResponse } from "next/server"; +import { getCachedResponse } from "@/lib/cache"; +import { invalidateCache } from "@/lib/cache-utils"; import db from "@/db/drizzle"; import { units } from "@/db/schema"; import { getIsAdmin } from "@/lib/admin"; -export const GET = async () => { - const isAdmin = getIsAdmin(); - if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 }); +export async function GET() { + try { + const isAdmin = getIsAdmin(); + if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 }); - const data = await db.query.units.findMany(); + const units = await getCachedResponse( + 'units', + async () => { + const result = await db.query.units.findMany(); + return result; + }, + 900 // 15 minutes cache + ); - return NextResponse.json(data); + return NextResponse.json(units); + } catch (error) { + console.error("Error fetching units:", error); + return NextResponse.json( + { error: "Failed to fetch units" }, + { status: 500 }, + ); + } }; export const POST = async (req: NextRequest) => { diff --git a/langsuit/lib/cache-utils.ts b/langsuit/lib/cache-utils.ts new file mode 100644 index 0000000..1c27b76 --- /dev/null +++ b/langsuit/lib/cache-utils.ts @@ -0,0 +1,26 @@ +import redis from "./redis"; + +/** + * Invalidates cache for a specific resource + * @param type - The type of resource (e.g., 'courses', 'units', 'lessons') + * @param id - Optional ID for specific resource + */ +export async function invalidateCache(type: string, id?: string | number) { + try { + // Get all keys matching the pattern + const keys = await redis.keys(`${type}*`); + + // Delete all matching keys + if (keys.length > 0) { + await redis.del(...keys); + } + + // If specific ID is provided, invalidate that specific key + if (id) { + const specificKey = `${type}:${id}`; + await redis.del(specificKey); + } + } catch (error) { + console.error(`Error invalidating cache for ${type}:`, error); + } +}