diff --git a/package.json b/package.json index 0e2ec18..a5614ae 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,13 @@ "dependencies": { "@material-ui/core": "4.11.3", "axios": "0.21.1", + "axios-extensions": "3.1.3", "clsx": "1.1.1", "dayjs": "1.10.4", "lodash.groupby": "4.6.0", "lodash.orderby": "4.6.0", + "lru-cache": "6.0.0", + "milliseconds": "1.0.3", "mobx": "6.1.7", "mobx-react": "7.1.0", "next": "10.0.7", @@ -42,6 +45,7 @@ "@next/bundle-analyzer": "10.0.7", "@types/lodash.groupby": "4.6.6", "@types/lodash.orderby": "4.6.6", + "@types/milliseconds": "0.0.30", "@types/node": "14.14.31", "@types/nprogress": "0.2.0", "@types/react": "17.0.2", diff --git a/src/components/pages/index-page/IndexPage.store.ts b/src/components/pages/index-page/IndexPage.store.ts index 2d94716..7795dd4 100644 --- a/src/components/pages/index-page/IndexPage.store.ts +++ b/src/components/pages/index-page/IndexPage.store.ts @@ -37,7 +37,7 @@ export class IndexPageStore { } *loadShow() { - const response: ApiResponse = yield getShowRequest(defaultShowId); + const response: ApiResponse = yield getShowRequest(defaultShowId, { cache: true, forceUpdate: false }); this.showResults = { data: this.showResults.data, diff --git a/src/domains/shows/shows.services.ts b/src/domains/shows/shows.services.ts index acab199..6f0ed0b 100644 --- a/src/domains/shows/shows.services.ts +++ b/src/domains/shows/shows.services.ts @@ -1,11 +1,12 @@ import environment from 'environment'; import { http } from '../../utils/http/http'; import { ICast, IEpisode, IShow } from './shows.types'; +import { AxiosRequestCacheRequest } from '../../utils/http/http.types'; -export const getShowRequest = async (showId: string) => { +export const getShowRequest = async (showId: string, cacheRequest?: AxiosRequestCacheRequest) => { const endpoint: string = environment.api.shows.replace(':showId', showId); - return http.get(endpoint); + return http.get(endpoint, {}, cacheRequest); }; export const getEpisodesRequest = async (showId: string) => { diff --git a/src/utils/http/http.ts b/src/utils/http/http.ts index 0cd632d..c7ed0ee 100644 --- a/src/utils/http/http.ts +++ b/src/utils/http/http.ts @@ -1,6 +1,22 @@ import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { ApiResponse, IApiError } from './http.types'; import { HttpVerbs } from './http.constants'; +import { cacheAdapterEnhancer } from 'axios-extensions'; +import environment from 'environment'; +import LRUCache from 'lru-cache'; +import ms from 'milliseconds'; + +if (environment.isDevelopment) { + // logger for cacheAdapterEnhancer + process.env.LOGGER_LEVEL = 'info'; +} + +const axiosWithCache = axios.create({ + adapter: cacheAdapterEnhancer(axios.defaults.adapter!, { + enabledByDefault: true, + defaultCache: new LRUCache({ maxAge: ms.minutes(1) }), + }), +}); const httpRequest = async ( method: HttpVerbs, @@ -21,7 +37,7 @@ const httpRequest = async ( }; try { - const response: AxiosResponse = await axios(requestConfig); + const response: AxiosResponse = await axiosWithCache(requestConfig); return { data: response.data, statusCode: response.status }; } catch (error) { diff --git a/src/utils/http/http.types.ts b/src/utils/http/http.types.ts index c6bfdf8..452db1a 100644 --- a/src/utils/http/http.types.ts +++ b/src/utils/http/http.types.ts @@ -1,3 +1,5 @@ +import { AxiosRequestConfig } from 'axios'; + export type SuccessfulResponse = { data: T; error?: never; statusCode?: number }; export type UnsuccessfulResponse = { data?: never; error: E; statusCode?: number }; @@ -6,3 +8,5 @@ export interface IApiError { } export type ApiResponse = SuccessfulResponse | UnsuccessfulResponse; + +export type AxiosRequestCacheRequest = Pick; diff --git a/yarn.lock b/yarn.lock index 2dc504c..5eb318e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,6 +280,16 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.167.tgz#ce7d78553e3c886d4ea643c37ec7edc20f16765e" integrity sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw== +"@types/lru-cache@^4.1.1": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-4.1.2.tgz#528ba392658055dba78fc3be906ca338a1a2d1c5" + integrity sha512-ve2IoUJClE+4S/sG2zoLGEHP6DCvqgyz7UkHZdiICdQaAYRaCXsRWfJlbL8B0KvUyo9lgzD+oR0YSy4YikFyFQ== + +"@types/milliseconds@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/milliseconds/-/milliseconds-0.0.30.tgz#d779ac94f9ba2187b8b84997f65b8ce950b3c13c" + integrity sha512-MVgBCpNG6tuPctUGqaGsbMLm5E4bYy8Ki7G4RMmcMH83e15iMY9L7bJccWpXv3Zyo8y0GQlvUj+yOShWlQlTOA== + "@types/minimatch@^3.0.3": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -633,6 +643,16 @@ axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf" integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ== +axios-extensions@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/axios-extensions/-/axios-extensions-3.1.3.tgz#cd745bb7dc899743f85a2b5a291c7f36d9f41e12" + integrity sha512-/OB9OcJLNOIx9pdW4m4/hFRvNo12wlX5BaprIzqpMaLR02I88Mr98/wW4QN9rhx0/yg9rM7i6Af/RpV4MyxXjA== + dependencies: + "@types/lru-cache" "^4.1.1" + lru-cache "^5.1.1" + tslib "^1.9.0" + util "^0.11.1" + axios@0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -2477,13 +2497,20 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@^6.0.0: +lru-cache@6.0.0, lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -2541,6 +2568,11 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" +milliseconds@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/milliseconds/-/milliseconds-1.0.3.tgz#1ff437c4f734b138ef7c2cedba4d8880c7f5c2d8" + integrity sha1-H/Q3xPc0sTjvfCztuk2IgMf1wtg= + mime@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -4087,7 +4119,7 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tslib@^1.8.1: +tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -4184,7 +4216,7 @@ util@0.10.3: dependencies: inherits "2.0.1" -util@^0.11.0: +util@^0.11.0, util@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== @@ -4318,6 +4350,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"