From 6749a33692a68491296770b801dac974e029667d Mon Sep 17 00:00:00 2001 From: Taha Abbasi Date: Thu, 30 Mar 2023 19:40:57 -0600 Subject: [PATCH 1/2] Added caching --- build/cacheMiddleware.js | 25 +++++++++++++++++++++++++ build/server.js | 30 ++++++++++++++++++++++++------ package-lock.json | 33 +++++++++++++++++++++++++++++++++ package.json | 1 + src/cacheMiddleware.ts | 25 +++++++++++++++++++++++++ src/server.ts | 36 +++++++++++++++++++++++++++++------- 6 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 build/cacheMiddleware.js create mode 100644 src/cacheMiddleware.ts diff --git a/build/cacheMiddleware.js b/build/cacheMiddleware.js new file mode 100644 index 0000000..5caa1c4 --- /dev/null +++ b/build/cacheMiddleware.js @@ -0,0 +1,25 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const node_cache_1 = __importDefault(require("node-cache")); +const cache = new node_cache_1.default({ stdTTL: 60 }); // 60 seconds TTL +const cacheMiddleware = (duration) => { + return (req, res, next) => { + const key = req.originalUrl; + const cachedResponse = cache.get(key); + if (cachedResponse) { + res.send(cachedResponse); + } + else { + const originalSend = res.send.bind(res); + res.send = ((body) => { + cache.set(key, body, duration); + originalSend(body); + }); + next(); + } + }; +}; +exports.default = cacheMiddleware; diff --git a/build/server.js b/build/server.js index e8780d6..a1b7d9c 100644 --- a/build/server.js +++ b/build/server.js @@ -18,10 +18,28 @@ const body_parser_1 = __importDefault(require("body-parser")); const bignumber_js_1 = __importDefault(require("bignumber.js")); const getSupplyAcrossNetworks_1 = require("./getSupplyAcrossNetworks"); const config_1 = require("./config"); +const cacheMiddleware_1 = __importDefault(require("./cacheMiddleware")); const app = (0, express_1.default)(); const port = process.env.PORT || 8080; +// const cache = new NodeCache({ stdTTL: 60 }); // 60 seconds TTL app.use(body_parser_1.default.json()); -app.get("/totalSupplyAcrossNetworks", (req, res) => __awaiter(void 0, void 0, void 0, function* () { +// const cacheMiddleware = (duration: number) => { +// return (req: Request, res: Response, next: NextFunction) => { +// const key = req.originalUrl; +// const cachedResponse = cache.get(key); +// if (cachedResponse) { +// res.send(cachedResponse); +// } else { +// const originalSend = res.send.bind(res); +// res.send = ((body: any) => { +// cache.set(key, body, duration); +// originalSend(body); +// }) as Response['send']; +// next(); +// } +// }; +// } +app.get("/totalSupplyAcrossNetworks", (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { @@ -36,7 +54,7 @@ app.get("/totalSupplyAcrossNetworks", (req, res) => __awaiter(void 0, void 0, vo res.status(500).json({ error: 'An error occurred while fetching the total supply.' }); } })); -app.get('/totalSupply', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +app.get('/totalSupply', (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { @@ -52,7 +70,7 @@ app.get('/totalSupply', (req, res) => __awaiter(void 0, void 0, void 0, function res.status(500).send('Error getting total supply'); } })); -app.get("/nonCirculatingSupplyAddresses", (req, res) => __awaiter(void 0, void 0, void 0, function* () { +app.get("/nonCirculatingSupplyAddresses", (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { res.status(400).json({ error: 'Both tokenContractAddress and chainId must be provided as query parameters.' }); @@ -61,7 +79,7 @@ app.get("/nonCirculatingSupplyAddresses", (req, res) => __awaiter(void 0, void 0 const nonCirculatingSupplyAddressConfigurations = yield (0, config_1.getNonCirculatingSupplyAddressConfigurations)(tokenContractAddress, Number(chainId)); res.json(nonCirculatingSupplyAddressConfigurations); })); -app.get('/nonCirculatingSupplyBalancesByAddress', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +app.get('/nonCirculatingSupplyBalancesByAddress', (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { @@ -76,7 +94,7 @@ app.get('/nonCirculatingSupplyBalancesByAddress', (req, res) => __awaiter(void 0 res.status(500).json({ error: 'Failed to fetch non-circulating supply balances' }); } })); -app.get('/nonCirculatingSupplyBalance', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +app.get('/nonCirculatingSupplyBalance', (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { @@ -92,7 +110,7 @@ app.get('/nonCirculatingSupplyBalance', (req, res) => __awaiter(void 0, void 0, res.status(500).json({ error: 'Failed to fetch non-circulating supply balances' }); } })); -app.get('/circulatingSupplyBalance', (req, res) => __awaiter(void 0, void 0, void 0, function* () { +app.get('/circulatingSupplyBalance', (0, cacheMiddleware_1.default)(60), (req, res) => __awaiter(void 0, void 0, void 0, function* () { try { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { diff --git a/package-lock.json b/package-lock.json index bf8f71f..985f06b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "bignumber.js": "^9.1.1", "body-parser": "^1.20.2", "express": "^4.18.2", + "node-cache": "^5.1.2", "web3": "^1.9.0" }, "devDependencies": { @@ -1177,6 +1178,14 @@ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -2624,6 +2633,17 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "dependencies": { + "clone": "2.x" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -5113,6 +5133,11 @@ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" + }, "clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -6265,6 +6290,14 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "requires": { + "clone": "2.x" + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", diff --git a/package.json b/package.json index a22a6e4..fa896c2 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "bignumber.js": "^9.1.1", "body-parser": "^1.20.2", "express": "^4.18.2", + "node-cache": "^5.1.2", "web3": "^1.9.0" }, "devDependencies": { diff --git a/src/cacheMiddleware.ts b/src/cacheMiddleware.ts new file mode 100644 index 0000000..4e9555d --- /dev/null +++ b/src/cacheMiddleware.ts @@ -0,0 +1,25 @@ +import { Request, Response, NextFunction } from "express"; +import NodeCache from "node-cache"; + +const cache = new NodeCache({ stdTTL: 60 }); // 60 seconds TTL + +const cacheMiddleware = (duration: number) => { + return (req: Request, res: Response, next: NextFunction) => { + const key = req.originalUrl; + const cachedResponse = cache.get(key); + + if (cachedResponse) { + res.send(cachedResponse); + } else { + const originalSend = res.send.bind(res); + + res.send = ((body: any) => { + cache.set(key, body, duration); + originalSend(body); + }) as Response['send']; + + next(); + } + }; + } +export default cacheMiddleware; diff --git a/src/server.ts b/src/server.ts index d5f48cf..e743d6a 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,19 +1,41 @@ // src/server.ts -import express from "express"; +import express, { Request, Response, NextFunction } from "express"; import bodyParser from 'body-parser'; import BigNumber from "bignumber.js"; import { getTotalSupplyAcrossNetworks, getNonCirculatingSupplyBalances } from "./getSupplyAcrossNetworks"; import { getNetworkConfigurations, getNonCirculatingSupplyAddressConfigurations } from "./config"; import { NonCirculatingSupplyBalance } from './types'; +import cacheMiddleware from './cacheMiddleware'; const app = express(); const port = process.env.PORT || 8080; +// const cache = new NodeCache({ stdTTL: 60 }); // 60 seconds TTL app.use(bodyParser.json()); -app.get("/totalSupplyAcrossNetworks", async (req, res) => { +// const cacheMiddleware = (duration: number) => { +// return (req: Request, res: Response, next: NextFunction) => { +// const key = req.originalUrl; +// const cachedResponse = cache.get(key); + +// if (cachedResponse) { +// res.send(cachedResponse); +// } else { +// const originalSend = res.send.bind(res); + +// res.send = ((body: any) => { +// cache.set(key, body, duration); +// originalSend(body); +// }) as Response['send']; + +// next(); +// } +// }; +// } + +app.get("/totalSupplyAcrossNetworks", cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query; @@ -30,7 +52,7 @@ app.get("/totalSupplyAcrossNetworks", async (req, res) => { } }); -app.get('/totalSupply', async (req, res) => { +app.get('/totalSupply', cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query; @@ -48,7 +70,7 @@ app.get('/totalSupply', async (req, res) => { } }); -app.get("/nonCirculatingSupplyAddresses", async (req, res) => { +app.get("/nonCirculatingSupplyAddresses", cacheMiddleware(60), async (req, res) => { const { tokenContractAddress, chainId } = req.query; if (typeof tokenContractAddress !== 'string' || typeof chainId !== 'string') { @@ -59,7 +81,7 @@ app.get("/nonCirculatingSupplyAddresses", async (req, res) => { res.json(nonCirculatingSupplyAddressConfigurations); }); -app.get('/nonCirculatingSupplyBalancesByAddress', async (req, res) => { +app.get('/nonCirculatingSupplyBalancesByAddress', cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query; @@ -75,7 +97,7 @@ app.get('/nonCirculatingSupplyBalancesByAddress', async (req, res) => { } }); -app.get('/nonCirculatingSupplyBalance', async (req, res) => { +app.get('/nonCirculatingSupplyBalance', cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query; @@ -92,7 +114,7 @@ app.get('/nonCirculatingSupplyBalance', async (req, res) => { } }); -app.get('/circulatingSupplyBalance', async (req, res) => { +app.get('/circulatingSupplyBalance', cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query; From 04a69300ecf06eab5d114068d67e7db1a41c7c95 Mon Sep 17 00:00:00 2001 From: Taha Abbasi Date: Thu, 30 Mar 2023 19:41:28 -0600 Subject: [PATCH 2/2] Added caching --- src/server.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/server.ts b/src/server.ts index e743d6a..0668498 100644 --- a/src/server.ts +++ b/src/server.ts @@ -11,30 +11,9 @@ import cacheMiddleware from './cacheMiddleware'; const app = express(); const port = process.env.PORT || 8080; -// const cache = new NodeCache({ stdTTL: 60 }); // 60 seconds TTL app.use(bodyParser.json()); -// const cacheMiddleware = (duration: number) => { -// return (req: Request, res: Response, next: NextFunction) => { -// const key = req.originalUrl; -// const cachedResponse = cache.get(key); - -// if (cachedResponse) { -// res.send(cachedResponse); -// } else { -// const originalSend = res.send.bind(res); - -// res.send = ((body: any) => { -// cache.set(key, body, duration); -// originalSend(body); -// }) as Response['send']; - -// next(); -// } -// }; -// } - app.get("/totalSupplyAcrossNetworks", cacheMiddleware(60), async (req, res) => { try { const { tokenContractAddress, chainId } = req.query;