Skip to content

Commit

Permalink
chore(api): setup services to be ready for redis
Browse files Browse the repository at this point in the history
  • Loading branch information
luke-h1 committed Aug 5, 2024
1 parent 54810a9 commit 93997f7
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 49 deletions.
5 changes: 1 addition & 4 deletions src/db/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ class RedisDatabase {
return [];
}

public async set(
key: 'pet' | 'pets' | 'user' | 'users',
data: string,
): Promise<boolean> {
public async set(key: string, data: string): Promise<boolean> {
const db = this.getInstance();
try {
const result = await db.set(key, data);
Expand Down
125 changes: 107 additions & 18 deletions src/services/__tests__/petService.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { PetStatus } from '@prisma/client';
import { CreatePetInput } from 'src/schema/pet.schema';
import { pets as mockPets } from '../../controllers/__mocks__/pet';
import { user } from '../../controllers/__mocks__/user';
import { db } from '../../db/prisma';
import testRedis from '../../test/redis';
import PetService from '../petService';

describe('petService', () => {
Expand All @@ -12,7 +13,7 @@ describe('petService', () => {
});

describe('getPets', () => {
test('it returns pets from the database', async () => {
test('returns pets from the database', async () => {
const u = await db.user.create({
data: user,
});
Expand All @@ -24,7 +25,6 @@ describe('petService', () => {
})),
});
const pets = await petService.getPets();
console.log('pets', pets);
expect(pets).toEqual([
...mockPets.map(pet => ({
...pet,
Expand All @@ -35,8 +35,10 @@ describe('petService', () => {
})),
]);
});
});

test('it returns pets from the cache', async () => {
describe('getPet', () => {
test('returns a pet from the database', async () => {
const u = await db.user.create({
data: user,
});
Expand All @@ -47,21 +49,108 @@ describe('petService', () => {
creatorId: u.id,
})),
});
// 1st call to populate cache
await petService.getPets();

// 2nd call to get pets from cache
const pets = await petService.getPets();
expect(pets).toEqual([
...mockPets.map(pet => ({
...pet,
creatorId: u.id,
id: expect.any(String),
createdAt: expect.any(String),
updatedAt: expect.any(String),
})),
]);
expect(testRedis.get).toHaveBeenCalledTimes(1);
const pets = await db.pet.findMany();

const pet = await petService.getPet(pets[0].id);
expect(pet).toEqual({
...mockPets[0],
creatorId: u.id,
id: expect.any(String),
createdAt: expect.any(Date),
updatedAt: expect.any(Date),
});
});
});

describe('createPet', () => {
test('can create a pet', async () => {
const u = await db.user.create({
data: user,
});

const pet: CreatePetInput['body'] = {
name: 'marbles',
description: 'marbles is a good cat',
age: '2',
birthDate: '2022-02-02',
breed: 'cat :)',
photoUrl:
'https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
status: PetStatus.AVAILABLE,
tags: ['cute', 'indoor'],
};

const result = await petService.createPet(pet, u.id);

expect(result).toEqual({
...pet,
creatorId: u.id,
id: expect.any(String),
createdAt: expect.any(Date),
updatedAt: expect.any(Date),
});
});
});

describe('updatePet', () => {
test('can update a pet', async () => {
const u = await db.user.create({
data: user,
});

const createdPet: CreatePetInput['body'] = {
name: 'marbles',
description: 'marbles is a good cat',
age: '2',
birthDate: '2022-02-02',
breed: 'cat :)',
photoUrl:
'https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
status: PetStatus.AVAILABLE,
tags: ['cute', 'indoor'],
};

const createdResult = await petService.createPet(createdPet, u.id);

const result = await petService.updatePet(createdResult.id, {
...createdPet,
name: 'Updated Pet',
});

expect(result).toEqual({
...createdPet,
name: 'Updated Pet',
id: expect.any(String),
createdAt: expect.any(Date),
updatedAt: expect.any(Date),
creatorId: u.id,
});
});
});

describe('deletePet', () => {
test('can delete pet', async () => {
const u = await db.user.create({
data: user,
});

const createdPet: CreatePetInput['body'] = {
name: 'marbles',
description: 'marbles is a good cat',
age: '2',
birthDate: '2022-02-02',
breed: 'cat :)',
photoUrl:
'https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2',
status: PetStatus.AVAILABLE,
tags: ['cute', 'indoor'],
};

const createdResult = await petService.createPet(createdPet, u.id);

const result = await petService.deletePet(createdResult.id);
expect(result).toEqual(null);
});
});
});
43 changes: 16 additions & 27 deletions src/services/petService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Pet } from '@prisma/client';
import { db } from '../db/prisma';
import RedisDatabase from '../db/redis';
import {
Expand All @@ -17,39 +16,36 @@ export default class PetService {
}

async getPets() {
const cachedPets = await this.redis.getAll<Pet[]>('pets');
// const cachedPets = await this.redis.getAll<Pet[]>('pets');

if (cachedPets && cachedPets.length) {
return JSON.parse(cachedPets as unknown as string);
}
// if (cachedPets && cachedPets.length) {
// return JSON.parse(cachedPets as unknown as string);
// }

const pets = await db.pet.findMany();

// save to cache
await this.redis.setWithExpr('pets', JSON.stringify(pets), {
time: 120,
token: 'EX',
});
// console.log('pets', JSON.stringify(pets, null, 2));
// await this.redis.set('pets', JSON.stringify(pets));

return pets;
}

async getPet(id: GetPetInput['params']['id']) {
const cachedPet = await this.redis.get<Pet>(`pet:${id}`);
if (cachedPet) {
return JSON.parse(cachedPet as unknown as string);
}
// const cachedPet = await this.redis.get<Pet>(`pet:${id}`);
// if (cachedPet) {
// return JSON.parse(cachedPet as unknown as string);
// }

const pet = await db.pet.findFirst({
where: {
id: id.toString(),
},
});

await this.redis.setWithExpr(`pet:${id}`, JSON.stringify(pet), {
time: 120,
token: 'EX',
});
// await this.redis.set(`pet:${id}`, JSON.stringify(pet));

// console.log('key is', `pet:${id}`);

return pet;
}
Expand All @@ -62,10 +58,7 @@ export default class PetService {
},
});

await this.redis.setWithExpr(`pet:${newPet.id}`, JSON.stringify(newPet), {
time: 120,
token: 'EX',
});
// await this.redis.set(`pet:${newPet.id}`, JSON.stringify(newPet));

return newPet;
}
Expand All @@ -83,18 +76,14 @@ export default class PetService {
},
});

await this.redis.setWithExpr(`pet:${id}`, JSON.stringify(updatedPet), {
time: 120,
token: 'EX',
});

// await this.redis.set(`pet:${id}`, JSON.stringify(updatedPet));
return updatedPet;
}

async deletePet(id: DeletePetInput['params']['id']) {
const result = await db.pet.delete({ where: { id: id.toString() } });

await this.redis.deleteItem(`pet:${id}`);
// await this.redis.deleteItem(`pet:${id}`);

logger.info('delete result', result);
return null;
Expand Down

0 comments on commit 93997f7

Please sign in to comment.