Skip to content

Commit

Permalink
add caching, change ice-cream retrieval from payload to query (#7)
Browse files Browse the repository at this point in the history
* add caching, change ice-cream retrieval from payload to query

* fix ice cream fetching, remove console logs

* fix expected http response code

* update validation pipe

---------

Co-authored-by: Dominik Maćkiewicz <[email protected]>
  • Loading branch information
mcdominik and Dominik Maćkiewicz authored Jan 22, 2024
1 parent 7de1a17 commit 6587f76
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 36 deletions.
45 changes: 45 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"dependencies": {
"@nestjs-modules/mailer": "^1.8.1",
"@nestjs/axios": "^2.0.0",
"@nestjs/cache-manager": "^2.2.0",
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.3.2",
"@nestjs/core": "^9.0.0",
Expand All @@ -32,6 +33,7 @@
"@nestjs/platform-express": "^9.0.0",
"@nestjs/swagger": "^6.3.0",
"bcryptjs": "^2.4.3",
"cache-manager": "^5.4.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"cloudinary": "^1.37.0",
Expand Down
17 changes: 15 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { ReviewsModule } from './reviews/reviews.module';
import { IceCreamsModule } from './ice-creams/ice-creams.module';
import { CloudinaryModule } from './cloudinary/cloudinary.module';
import { UserProfileModule } from './user-profile/user-profile.module';

import { CacheModule } from '@nestjs/cache-manager';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { CacheInterceptor } from '@nestjs/cache-manager';
@Module({})
export class AppModule {
static forRoot(options?: {
Expand All @@ -25,13 +27,24 @@ export class AppModule {
}@${options?.mongoHost ?? process.env.MONGO_HOST}/admin`,
{ dbName: 'icebunch' },
),
CacheModule.register({
ttl: 86400000,
max: 10,
isGlobal: true,
}),
AuthModule,
CloudinaryModule,
UsersModule,
MailsModule,
UserProfileModule,
IceCreamsModule,
ReviewsModule
ReviewsModule,
],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: CacheInterceptor,
},
],
};
}
Expand Down
9 changes: 7 additions & 2 deletions src/ice-creams/dto/search-query.dto.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { Type } from 'class-transformer';
import {
IsBoolean,
IsInt,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';

export class SearchQueryDto {
@IsString()
@IsOptional()
searchField: string;

@IsBoolean()
@IsOptional()
@Type(() => Boolean)
isVegan: boolean;

@IsNotEmpty()
sortType: Sort;

@IsNumber()
@IsInt()
@Type(() => Number)
page: number;
}

Expand Down
16 changes: 5 additions & 11 deletions src/ice-creams/ice-creams.controller.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
} from '@nestjs/common';
import { Controller, Get, Param, UseInterceptors, Query } from '@nestjs/common';
import { IceCreamsService } from './ice-creams.service';
import { CreateIceCreamDto } from './dto/create-ice-cream.dto';
import { SearchQueryDto } from './dto/search-query.dto';
import { CacheInterceptor } from '@nestjs/cache-manager';

@UseInterceptors(CacheInterceptor)
@Controller('ice-creams')
export class IceCreamsController {
constructor(private readonly iceCreamsService: IceCreamsService) {}
Expand All @@ -20,8 +14,8 @@ export class IceCreamsController {
// return this.iceCreamsService.addNew(dto);
// }

@Post()
findAndSortWithPagination(@Body() dto: SearchQueryDto) {
@Get()
findAndSortWithPagination(@Query() dto: SearchQueryDto) {
return this.iceCreamsService.findAndSortWithPagination(dto);
}

Expand Down
2 changes: 0 additions & 2 deletions src/ice-creams/ice-creams.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ import { IceCreamsService } from './ice-creams.service';
import { IceCreamsController } from './ice-creams.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { IceCreamSchema, IceCream } from './entities/ice-cream.entity';
// import { ReviewsModule } from 'src/reviews/reviews.module';

@Module({
imports: [
MongooseModule.forFeature([
{ name: IceCream.name, schema: IceCreamSchema },
]),
// ReviewsModule,
],
controllers: [IceCreamsController],
providers: [IceCreamsService],
Expand Down
6 changes: 4 additions & 2 deletions src/ice-creams/ice-creams.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { CreateIceCreamDto } from './dto/create-ice-cream.dto';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
Expand All @@ -7,11 +7,14 @@ import { SearchQueryDto, Sort } from './dto/search-query.dto';
import { OurExceptionType } from 'src/common/errors/OurExceptionType';
import { OurHttpException } from 'src/common/errors/OurHttpException';
import { IceCreamQuery } from './types/ice-cream.query';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';

@Injectable()
export class IceCreamsService {
private ICES_ON_PAGE = 20;
constructor(
@Inject(CACHE_MANAGER) private cacheManager: Cache,
@InjectModel(IceCream.name) private iceCreamModel: Model<IceCreamDocument>,
) {}

Expand All @@ -36,7 +39,6 @@ export class IceCreamsService {
throw new OurHttpException(OurExceptionType.UNKNOW_SORTING_KEY);
}
}

async findAndSortWithPagination(dto: SearchQueryDto): Promise<IceCreamQuery> {
const totalEntitiesCount = await this.iceCreamModel.count();
const queryEntitiesCount = await this.getCountMatchingSearchQuery(dto);
Expand Down
32 changes: 15 additions & 17 deletions test/ice-cream.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,18 @@ describe('reviews', () => {
await createIceCream({ vegan: false });
await createIceCream({ vegan: true });

const searchQueryDto: SearchQueryDto = {
searchField: 'brand_pl',
const dto: Partial<SearchQueryDto> = {
isVegan: true,
sortType: Sort.MOST_POPULAR,
page: 1,
};

// when
const response = await request(app.getHttpServer())
.post('/ice-creams')
.send(searchQueryDto);
const response = await request(app.getHttpServer()).get(
`/ice-creams?isVegan=${dto.isVegan}&sortType=${dto.sortType}&page=${dto.page}`,
);
// then
expect(response.status).toBe(201);
expect(response.status).toBe(200);
for (const iceCream of response.body.iceCreams) {
expect(iceCream.vegan).toBe(true);
}
Expand All @@ -150,18 +149,18 @@ describe('reviews', () => {
await createIceCream({ name_en: 'different' });
await createIceCream({ name_en: 'different' });

const searchQueryDto: SearchQueryDto = {
const dto: Partial<SearchQueryDto> = {
searchField: 'Ben Jerry',
isVegan: undefined,
sortType: Sort.MOST_POPULAR,
page: 1,
};

// when
const response = await request(app.getHttpServer())
.post('/ice-creams')
.send(searchQueryDto);
const response = await request(app.getHttpServer()).get(
`/ice-creams?searchField=${dto.searchField}&sortType=${dto.sortType}&page=${dto.page}`,
);
// then
expect(response.status).toBe(200);
expect(response.body.iceCreams.length).toEqual(1);
});

Expand All @@ -171,18 +170,17 @@ describe('reviews', () => {
await createIceCream({ name_en: 'most popular', numberOfRatings: 3 });
await createIceCream({ numberOfRatings: 1 });

const searchQueryDto: SearchQueryDto = {
searchField: '',
isVegan: undefined,
const dto: Partial<SearchQueryDto> = {
sortType: Sort.MOST_POPULAR,
page: 1,
};

// when
const response = await request(app.getHttpServer())
.post('/ice-creams')
.send(searchQueryDto);
const response = await request(app.getHttpServer()).get(
`/ice-creams?sortType=${dto.sortType}&page=${dto.page}`,
);
// then
expect(response.status).toBe(200);
expect(response.body.iceCreams[0].name_en).toEqual('most popular');
});

Expand Down

0 comments on commit 6587f76

Please sign in to comment.