Merged in feature/redis (pull request #1478)
Distributed cache * cache deleteKey now uses an options object instead of a lonely argument variable fuzzy * merge * remove debug logs and cleanup * cleanup * add fault handling * add fault handling * add pid when logging redis client creation * add identifier when logging redis client creation * cleanup * feat: add redis-api as it's own app * feature: use http wrapper for redis * feat: add the possibility to fallback to unstable_cache * Add error handling if redis cache is unresponsive * add logging for unstable_cache * merge * don't cache errors * fix: metadatabase on branchdeploys * Handle when /en/destinations throws add ErrorBoundary * Add sentry-logging when ErrorBoundary catches exception * Fix error handling for distributed cache * cleanup code * Added Application Insights back * Update generateApiKeys script and remove duplicate * Merge branch 'feature/redis' of bitbucket.org:scandic-swap/web into feature/redis * merge Approved-by: Linus Flood
This commit is contained in:
committed by
Linus Flood
parent
a8304e543e
commit
fa63b20ed0
93
apps/redis-api/src/routes/api/cache.ts
Normal file
93
apps/redis-api/src/routes/api/cache.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Elysia, t, ValidationError } from "elysia";
|
||||
import { redis } from "@/services/redis";
|
||||
import { ModelValidationError } from "@/errors/ModelValidationError";
|
||||
|
||||
const MIN_LENGTH = 1;
|
||||
|
||||
const QUERY_TYPE = t.Object({ key: t.String({ minLength: MIN_LENGTH }) });
|
||||
|
||||
export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
||||
.get(
|
||||
"/",
|
||||
async ({ query: { key }, error }) => {
|
||||
key = validateKey(key);
|
||||
console.log("GET /cache", key);
|
||||
|
||||
const value = await redis.get(key);
|
||||
if (!value) {
|
||||
return error("Not Found", "Not Found");
|
||||
}
|
||||
|
||||
try {
|
||||
const output = JSON.parse(value);
|
||||
return { data: output };
|
||||
} catch (e) {
|
||||
redis.del(key);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
{
|
||||
query: QUERY_TYPE,
|
||||
response: { 200: t.Object({ data: t.Any() }), 404: t.String() },
|
||||
}
|
||||
)
|
||||
.put(
|
||||
"/",
|
||||
async ({ query: { key }, body, error, set }) => {
|
||||
key = validateKey(key);
|
||||
console.log("PUT /cache", key);
|
||||
|
||||
if (!body.ttl || body.ttl < 0) {
|
||||
return error("Bad Request", "ttl is required");
|
||||
}
|
||||
|
||||
await redis.set(key, JSON.stringify(body.data), "EX", body.ttl);
|
||||
|
||||
set.status = 204;
|
||||
return;
|
||||
},
|
||||
{
|
||||
body: t.Object({ data: t.Any(), ttl: t.Number() }),
|
||||
query: QUERY_TYPE,
|
||||
response: { 204: t.Void(), 400: t.String() },
|
||||
}
|
||||
)
|
||||
.delete(
|
||||
"/",
|
||||
async ({ query: { key, fuzzy }, set }) => {
|
||||
key = validateKey(key);
|
||||
console.log("DELETE /cache", key);
|
||||
|
||||
if (fuzzy) {
|
||||
key = `*${key}*`;
|
||||
}
|
||||
|
||||
await redis.del(key);
|
||||
|
||||
set.status = 204;
|
||||
return;
|
||||
},
|
||||
{
|
||||
query: t.Object({
|
||||
...QUERY_TYPE.properties,
|
||||
...t.Object({ fuzzy: t.Optional(t.Boolean()) }).properties,
|
||||
}),
|
||||
response: { 204: t.Void(), 400: t.String() },
|
||||
}
|
||||
);
|
||||
|
||||
function validateKey(key: string) {
|
||||
const parsedKey = decodeURIComponent(key);
|
||||
|
||||
if (parsedKey.length < MIN_LENGTH) {
|
||||
throw new ModelValidationError(
|
||||
"Key has to be atleast 1 character long"
|
||||
);
|
||||
}
|
||||
|
||||
if (parsedKey.includes("*")) {
|
||||
throw new ModelValidationError("Key cannot contain wildcards");
|
||||
}
|
||||
|
||||
return parsedKey;
|
||||
}
|
||||
7
apps/redis-api/src/routes/api/index.ts
Normal file
7
apps/redis-api/src/routes/api/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Elysia } from "elysia";
|
||||
import { cacheRoutes } from "./cache";
|
||||
import { apiKeyMiddleware } from "@/middleware/apiKeyMiddleware";
|
||||
|
||||
export const apiRoutes = new Elysia({ prefix: "/api" })
|
||||
.guard({ beforeHandle: apiKeyMiddleware })
|
||||
.use(cacheRoutes);
|
||||
Reference in New Issue
Block a user