Skip to content

Commit

Permalink
Cached posts and ratelimited api
Browse files Browse the repository at this point in the history
  • Loading branch information
tanish35 committed Oct 24, 2024
1 parent d71b50e commit b5fad3a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 12 deletions.
10 changes: 10 additions & 0 deletions backend/src/controllers/postController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ const fetchPosts = asyncHandler(async (req: Request, res: Response) => {
const postsPerPage = 4;
const offset = (pageNumber - 1) * postsPerPage;

const cacheKey = `posts:${collegeId || "all"}:page:${pageNumber}`;

const cachedResults = await getCachedData(cacheKey);
if (cachedResults) {
return res.status(200).json(JSON.parse(cachedResults));
}

const posts = await prisma.post.findMany({
where: collegeId ? { college_id: collegeId } : {},
orderBy: {
Expand Down Expand Up @@ -170,6 +177,9 @@ const fetchPosts = asyncHandler(async (req: Request, res: Response) => {
const totalPosts = await prisma.post.count();
const isOver = offset + postsPerPage >= totalPosts;

const result = { posts, isOver };
await setCachedData(cacheKey, JSON.stringify(result), 600);

return res.status(200).json({ posts, isOver });
});

Expand Down
40 changes: 40 additions & 0 deletions backend/src/middleware/rateLimit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Request, Response, NextFunction } from "express";
import asyncHandler from "express-async-handler";
import Redis from "ioredis";

const redisUrl = process.env.REDIS_URL;
if (!redisUrl) {
throw new Error("REDIS_URL is not defined");
}
const redis = new Redis(redisUrl);
const MAX_REQUESTS = 100;
const WINDOW_SIZE_IN_SECONDS = 60;

const rateLimiter = asyncHandler(
//@ts-ignore
async (req: Request, res: Response, next: NextFunction) => {
//@ts-ignore
const clientIp = req.user.user_id;
// console.log(clientIp);
const key = `rate-limit:${clientIp}`;
const requestCount = await redis.get(key);

if (requestCount && parseInt(requestCount) >= MAX_REQUESTS) {
return res
.status(429)
.json({ message: "Too many requests, please try again later." });
}

const ttl = await redis.ttl(key);

if (ttl < 0) {
await redis.set(key, 1, "EX", WINDOW_SIZE_IN_SECONDS);
} else {
await redis.incr(key);
}

next();
}
);

export default rateLimiter;
25 changes: 13 additions & 12 deletions backend/src/routes/postsRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@ import {
deletePost,
} from "../controllers/postController";
import checkAuth from "../middleware/checkAuth";
import rateLimiter from "../middleware/rateLimit";

const postsRoutes = express.Router();

postsRoutes.get("/communities", checkAuth, getCommunities);
postsRoutes.post("/create", checkAuth, createPost);
postsRoutes.post("/fetch", checkAuth, fetchPosts);
postsRoutes.post("/like", checkAuth, likePost);
postsRoutes.get("/fetch/:id", checkAuth, fetchSinglePost);
postsRoutes.post("/comment", checkAuth, createComment);
postsRoutes.post("/liked", checkAuth, postLiked);
postsRoutes.post("/unlike", checkAuth, unlikePost);
postsRoutes.post("/search", checkAuth, searchPosts);
postsRoutes.get("/allcommunities", checkAuth, getAllCommunities);
postsRoutes.post("/deletecomment", checkAuth, deleteComment);
postsRoutes.post("/deletepost", checkAuth, deletePost);
postsRoutes.get("/communities", checkAuth, rateLimiter, getCommunities);
postsRoutes.post("/create", checkAuth, rateLimiter, createPost);
postsRoutes.post("/fetch", checkAuth, rateLimiter, fetchPosts);
postsRoutes.post("/like", checkAuth, rateLimiter, likePost);
postsRoutes.get("/fetch/:id", checkAuth, rateLimiter, fetchSinglePost);
postsRoutes.post("/comment", checkAuth, rateLimiter, createComment);
postsRoutes.post("/liked", checkAuth, rateLimiter, postLiked);
postsRoutes.post("/unlike", checkAuth, rateLimiter, unlikePost);
postsRoutes.post("/search", checkAuth, rateLimiter, searchPosts);
postsRoutes.get("/allcommunities", checkAuth, rateLimiter, getAllCommunities);
postsRoutes.post("/deletecomment", checkAuth, rateLimiter, deleteComment);
postsRoutes.post("/deletepost", checkAuth, rateLimiter, deletePost);

export default postsRoutes;

0 comments on commit b5fad3a

Please sign in to comment.