Skip to content

Commit

Permalink
feat: add 60s caching to api
Browse files Browse the repository at this point in the history
  • Loading branch information
0xkenj1 committed Aug 22, 2024
1 parent b3338ed commit e7fbb90
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
3 changes: 2 additions & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
"test:cov": "vitest run --config vitest.config.ts --coverage"
},
"dependencies": {
"@zkchainhub/chain-providers": "workspace:*",
"@zkchainhub/metrics": "workspace:*",
"@zkchainhub/pricing": "workspace:*",
"@zkchainhub/chain-providers": "workspace:*",
"@zkchainhub/shared": "workspace:*",
"bignumber.js": "9.1.2",
"cache-manager": "5.7.6",
"cors": "2.8.5",
"dotenv": "16.4.5",
"express": "4.19.2",
"node-cache": "5.1.2",
"swagger-ui-express": "5.0.1",
"viem": "2.19.6",
"yaml": "2.5.0",
Expand Down
36 changes: 36 additions & 0 deletions apps/api/src/common/middleware/cache.middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { NextFunction, Request, Response } from "express";
import NodeCache from "node-cache";

const DEFAULT_TTL = 60; // 1 minute
const cache = new NodeCache();

//FIXME: This is a temporary cache implementation. It is not recommended for production use.
// might be replaced with a more robust solution in the future.
/**
* A middleware that caches responses for a given time to live (TTL).
* @param args - The time to live (TTL) in seconds for the cached response.
* @returns A middleware function that caches responses for a given time to live (TTL).
*/
export function cacheMiddleware(args: { ttl: number } = { ttl: DEFAULT_TTL }) {
return async (req: Request, res: Response, next: NextFunction): Promise<void> => {
const key = req.originalUrl || req.url;
const cachedResponse = await cache.get(key);
if (cachedResponse) {
// Check if the cached response is a JSON object or plain text
res.json(cachedResponse);
} else {
// Store the original send and json functions
const originalJson = res.json.bind(res);
// Override the json function

res.json = (body): Response => {
// Cache the response body
cache.set(key, body, args.ttl);
// Call the original json function with the response body
return originalJson(body);
};

next();
}
};
}
5 changes: 3 additions & 2 deletions apps/api/src/metrics/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z } from "zod";

import { ILogger } from "@zkchainhub/shared";

import { cacheMiddleware } from "../../common/middleware/cache.middleware.js";
import { BaseRouter } from "../../common/routes/baseRouter.js";
import { ChainNotFound, MetricsController } from "../index.js";

Expand All @@ -27,7 +28,7 @@ export class MetricsRouter extends BaseRouter {
* Retrieves the ecosystem information.
* @returns {Promise<EcosystemInfo>} The ecosystem information.
*/
this.router.get("/ecosystem", async (_req, res, next) => {
this.router.get("/ecosystem", cacheMiddleware(), async (_req, res, next) => {
try {
const data = await this.metricsController.getEcosystem();
res.json(data);
Expand All @@ -42,7 +43,7 @@ export class MetricsRouter extends BaseRouter {
* @param {number} chainId - The ID of the chain.
* @returns {Promise<ZKChainInfo>} The chain information.
*/
this.router.get("/zkchain/:chainId", async (req, res, next) => {
this.router.get("/zkchain/:chainId", cacheMiddleware(), async (req, res, next) => {
try {
const { params } = ChainIdSchema.parse(req);

Expand Down
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e7fbb90

Please sign in to comment.