What is the best way to handle a caching layer?
Hey, I am currently using upstash redis to cache one of my queries. However since using a cache in my router folder, I have to create a temporary interface to make typescript happy with the output as I cannot infer the types from the router.
Just wondering, what is the best approach for something like this.
Cheers!
Just wondering, what is the best approach for something like this.
Cheers!
// clientRouter.ts
interface cacheOutput {
paginatedClientsObject: {
id: string;
name: string;
description: string;
created_at: Date;
author_id: string;
}[];
rowCount: number;
}
const redisClient = new Redis(env.REDIS_URL);
const clientRepository = new SortedItemRepository('sorted-clients', redisClient);
export const clientRouter = createTRPCRouter({
getAllPaginated: protectedProcedure
.input(z.object({ skip: z.number(), take: z.number() }))
.query(async ({ ctx, input }) => {
const redisCache = await clientRepository.getById(`paginatedClients-${input.skip}`);
if (redisCache?.data) {
console.log('DATA FROM CACHE');
const cacheOutput = JSON.parse(redisCache.data as string) as cacheOutput;
return cacheOutput;
} else {
const paginatedClientsandRows = await ctx.prisma.$transaction(async (tx) => {
const rowCount = await tx.client.count();
const paginatedClients = await tx.client.findMany({
skip: input.skip * input.take,
take: input.take,
});
const paginatedClientsObject = paginatedClients.map((client) => ({
id: client.id,
name: client.name,
description: client.description,
created_at: client.createdAt,
author_id: client.authorId,
}));
return { paginatedClientsObject, rowCount };
});
await clientRepository.set({
id: `paginatedClients-${input.skip}`,
data: JSON.stringify(paginatedClientsandRows),
});
console.log('DATA FROM QUERY', paginatedClientsandRows);
return paginatedClientsandRows;
}
}),// clientRouter.ts
interface cacheOutput {
paginatedClientsObject: {
id: string;
name: string;
description: string;
created_at: Date;
author_id: string;
}[];
rowCount: number;
}
const redisClient = new Redis(env.REDIS_URL);
const clientRepository = new SortedItemRepository('sorted-clients', redisClient);
export const clientRouter = createTRPCRouter({
getAllPaginated: protectedProcedure
.input(z.object({ skip: z.number(), take: z.number() }))
.query(async ({ ctx, input }) => {
const redisCache = await clientRepository.getById(`paginatedClients-${input.skip}`);
if (redisCache?.data) {
console.log('DATA FROM CACHE');
const cacheOutput = JSON.parse(redisCache.data as string) as cacheOutput;
return cacheOutput;
} else {
const paginatedClientsandRows = await ctx.prisma.$transaction(async (tx) => {
const rowCount = await tx.client.count();
const paginatedClients = await tx.client.findMany({
skip: input.skip * input.take,
take: input.take,
});
const paginatedClientsObject = paginatedClients.map((client) => ({
id: client.id,
name: client.name,
description: client.description,
created_at: client.createdAt,
author_id: client.authorId,
}));
return { paginatedClientsObject, rowCount };
});
await clientRepository.set({
id: `paginatedClients-${input.skip}`,
data: JSON.stringify(paginatedClientsandRows),
});
console.log('DATA FROM QUERY', paginatedClientsandRows);
return paginatedClientsandRows;
}
}),