Skip to content

Commit

Permalink
feat: add caching at the server level rather than sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcdo29 committed Oct 23, 2023
1 parent d3cecf9 commit 55da787
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 17 deletions.
2 changes: 1 addition & 1 deletion apps/server-e2e/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"run-migrations": {
"executor": "nx:run-commands",
"options": {
"command": "pnpm nx run kysely-cli:e2e"
"command": "pnpm nx run cli:e2e"
},
"dependsOn": ["start-docker"]
},
Expand Down
18 changes: 18 additions & 0 deletions libs/server/cache/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
3 changes: 3 additions & 0 deletions libs/server/cache/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# server-cache

This library was generated with [Nx](https://nx.dev).
16 changes: 16 additions & 0 deletions libs/server/cache/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "server-cache",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/server/cache/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nx/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/server/cache/**/*.ts"]
}
}
},
"tags": ["server", "utility"]
}
2 changes: 2 additions & 0 deletions libs/server/cache/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./lib/cache-skip.decorator";
export * from "./lib/cache.interceptor";
4 changes: 4 additions & 0 deletions libs/server/cache/src/lib/cache-skip.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { SetMetadata } from "@nestjs/common";
import { CACHE_SKIP } from "./cache.constants";

export const CacheSkip = (skip = true) => SetMetadata(CACHE_SKIP, skip);
1 change: 1 addition & 0 deletions libs/server/cache/src/lib/cache.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const CACHE_SKIP = Symbol("METADATA:CACHE_SKIP");
23 changes: 23 additions & 0 deletions libs/server/cache/src/lib/cache.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { CacheInterceptor as NestCacheInterceptor } from "@nestjs/cache-manager";
import { ExecutionContext, Injectable } from "@nestjs/common";
import { CACHE_SKIP } from "./cache.constants";

@Injectable()
export class CacheInterceptor extends NestCacheInterceptor {
protected override trackBy(context: ExecutionContext): string | undefined {
const originalKey = super.trackBy(context);
if (originalKey?.includes("csrf")) {
const req = context.switchToHttp().getRequest();
return `${req.ips?.length ? req.ips[0] : req.ip}:${originalKey}`;
}
return originalKey;
}

protected override isRequestCacheable(context: ExecutionContext): boolean {
const skip = this.reflector.getAllAndOverride<boolean | undefined>(
CACHE_SKIP,
[context.getClass(), context.getHandler()],
);
return skip !== undefined ? !skip : super.isRequestCacheable(context);
}
}
19 changes: 19 additions & 0 deletions libs/server/cache/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}
16 changes: 16 additions & 0 deletions libs/server/cache/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../../dist/out-tsc",
"declaration": true,
"types": ["node"],
"target": "es2021",
"strictNullChecks": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
24 changes: 23 additions & 1 deletion libs/server/root/src/lib/root.module.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { ValidationPipe } from "@nest-lab/typeschema";
import { CacheManagerOptions, CacheModule } from "@nestjs/cache-manager";
import { Module } from "@nestjs/common";
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR, APP_PIPE } from "@nestjs/core";
import { OgmaInterceptor } from "@ogma/nestjs-module";
import { CacheInterceptor } from "@unteris/server/cache";
import { ServerConfigModule } from "@unteris/server/config";
import { ServerCsrfModule } from "@unteris/server/csrf";
import { ServerDeitiesModule } from "@unteris/server/deities";
import { ServerEmailModule } from "@unteris/server/email";
import { ServerLocationModule } from "@unteris/server/location";
import { ServerLoggingModule } from "@unteris/server/logging";
import { ServerRaceModule } from "@unteris/server/race";
import { ServerRedisModule, getInstanceToken } from "@unteris/server/redis";
import {
IsLoggedInGuard,
ServerSecurityModule,
Expand All @@ -17,14 +20,29 @@ import {
ServerSessionModule,
SessionExistsGuard,
} from "@unteris/server/session";
import { redisInsStore } from "cache-manager-redis-yet";
import { CookieModule, CookiesInterceptor } from "nest-cookies";

import type { RedisClientType } from "redis";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { BaseFilter } from "./catch-all.filter";

@Module({
imports: [
CacheModule.registerAsync({
inject: [getInstanceToken()],
useFactory: (redis: RedisClientType): CacheManagerOptions => {
return {
store: redisInsStore(
redis as unknown as Parameters<typeof redisInsStore>[0],
{
ttl: 60 * 60 * 1000,
},
),
};
},
imports: [ServerRedisModule],
}),
CookieModule,
ServerDeitiesModule,
ServerLocationModule,
Expand Down Expand Up @@ -55,6 +73,10 @@ import { BaseFilter } from "./catch-all.filter";
provide: APP_INTERCEPTOR,
useClass: OgmaInterceptor,
},
{
provide: APP_INTERCEPTOR,
useClass: CacheInterceptor,
},
{
provide: APP_FILTER,
useClass: BaseFilter,
Expand Down
2 changes: 2 additions & 0 deletions libs/server/security/src/lib/security.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
UseGuards,
} from "@nestjs/common";
import { ApiConsumes } from "@nestjs/swagger";
import { CacheSkip } from "@unteris/server/cache";
import { UnterisCookies, UnterisSession } from "@unteris/server/common";
import { CsrfGuard } from "@unteris/server/csrf";
import { SkipSessionCheck } from "@unteris/server/session";
Expand Down Expand Up @@ -74,6 +75,7 @@ export class ServerSecurityController {
}

@Get("me")
@CacheSkip()
@SkipSessionCheck(false)
async getMe(@Req() { user }: { user: UserAccount }) {
return user;
Expand Down
2 changes: 2 additions & 0 deletions libs/server/session/src/lib/session.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Controller, Get, Req, UseGuards } from "@nestjs/common";
import { CacheSkip } from "@unteris/server/cache";
import { RefreshRequest, UnterisCookies } from "@unteris/server/common";
import { sessionRoute } from "@unteris/shared/types";
import { Cookie, Cookies, NewCookies } from "nest-cookies";
Expand All @@ -11,6 +12,7 @@ export class SessionController {
constructor(private readonly sessionService: ServerSessionService) {}
@Get("refresh")
@UseGuards(RefreshSessionGuard)
@CacheSkip()
@SkipSessionCheck()
async refreshSession(
@Cookies() cookies: UnterisCookies,
Expand Down
12 changes: 2 additions & 10 deletions libs/shared/sdk/src/lib/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export class FetchError extends Error {

abstract class SdkBase<T extends SdkGeneric = RouteToType> {
private csrfToken = "";
private cache = new Map<string, T["get"][keyof T["get"]][0]>();
constructor(private readonly baseUrl: string) {}

setCsrfToken(token: string): SdkBase<T> {
Expand Down Expand Up @@ -64,16 +63,9 @@ abstract class SdkBase<T extends SdkGeneric = RouteToType> {
get<E extends keyof T["get"]>(
endpoint: E,
config: Record<string, string> = {},
ignoreCache = false,
): Promise<T["get"][E][0]> {
const reqConfig = { endpoint, method: "get", headers: config } as const;
const cacheKey = JSON.stringify(reqConfig);
const cacheVal = this.cache.get(cacheKey);
if (!ignoreCache && cacheVal) {
return cacheVal;
}
const res = this.request(reqConfig);
this.cache.set(cacheKey, res);
return res;
}

Expand Down Expand Up @@ -134,7 +126,7 @@ export class Sdk extends SdkBase {
}

async getCsrfToken() {
return this.get(csrfRoute, {}, true);
return this.get(csrfRoute, {});
}

async getUser() {
Expand All @@ -154,7 +146,7 @@ export class Sdk extends SdkBase {
}

async getSessionRefresh() {
return this.get(`${sessionRoute}/refresh`, {}, true);
return this.get(`${sessionRoute}/refresh`, {});
}

async getDeitiesByCategory(id: string) {
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"dependencies": {
"@commitlint/config-conventional": "^17.1.0",
"@nest-lab/typeschema": "^0.2.0",
"@nestjs/cache-manager": "^2.1.0",
"@nestjs/common": "10.1.3",
"@nestjs/core": "10.1.3",
"@nestjs/microservices": "^10.1.3",
Expand All @@ -34,6 +35,8 @@
"amqplib": "^0.10.3",
"argon2": "^0.30.3",
"axios": "^1.0.0",
"cache-manager": "^5.2.4",
"cache-manager-redis-yet": "^4.1.2",
"jotai": "^2.2.2",
"kysely": "^0.26.1",
"nest-commander": "^3.9.0",
Expand Down
Loading

0 comments on commit 55da787

Please sign in to comment.