Skip to content

Commit

Permalink
perf(core): Cache certain field resolvers to avoid duplicated DB calls
Browse files Browse the repository at this point in the history
Fixes #1119
  • Loading branch information
michaelbromley committed Sep 28, 2021
1 parent 6e7e864 commit 13697c3
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 7 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/api/api-internal-modules.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';

import { CacheModule } from '../cache/cache.module';
import { ConfigModule } from '../config/config.module';
import { DataImportModule } from '../data-import/data-import.module';
import { JobQueueModule } from '../job-queue/job-queue.module';
Expand Down Expand Up @@ -152,10 +153,11 @@ export const adminEntityResolvers = [
* one API module.
*/
@Module({
imports: [ConfigModule, ServiceModule.forRoot()],
imports: [ConfigModule, ServiceModule.forRoot(), CacheModule],
providers: [IdCodecService, ConfigurableOperationCodec, CustomFieldRelationResolverService],
exports: [
IdCodecService,
CacheModule,
ConfigModule,
ConfigurableOperationCodec,
CustomFieldRelationResolverService,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Parent, ResolveField, Resolver } from '@nestjs/graphql';

import { RequestContextCacheService } from '../../../cache/request-context-cache.service';
import { FacetValue } from '../../../entity/facet-value/facet-value.entity';
import { Facet } from '../../../entity/facet/facet.entity';
import { LocaleStringHydrator } from '../../../service/helpers/locale-string-hydrator/locale-string-hydrator';
Expand All @@ -12,6 +13,7 @@ export class FacetEntityResolver {
constructor(
private facetValueService: FacetValueService,
private localeStringHydrator: LocaleStringHydrator,
private requestContextCache: RequestContextCacheService,
) {}

@ResolveField()
Expand All @@ -24,6 +26,8 @@ export class FacetEntityResolver {
if (facet.values) {
return facet.values;
}
return this.facetValueService.findByFacetId(ctx, facet.id);
return this.requestContextCache.get(ctx, `FacetEntityResolver.values(${facet.id})`, () =>
this.facetValueService.findByFacetId(ctx, facet.id),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Parent, ResolveField, Resolver } from '@nestjs/graphql';

import { RequestContextCacheService } from '../../../cache/request-context-cache.service';
import { FacetValue } from '../../../entity/facet-value/facet-value.entity';
import { Facet } from '../../../entity/facet/facet.entity';
import { LocaleStringHydrator } from '../../../service/helpers/locale-string-hydrator/locale-string-hydrator';
Expand All @@ -9,7 +10,11 @@ import { Ctx } from '../../decorators/request-context.decorator';

@Resolver('FacetValue')
export class FacetValueEntityResolver {
constructor(private facetService: FacetService, private localeStringHydrator: LocaleStringHydrator) {}
constructor(
private facetService: FacetService,
private localeStringHydrator: LocaleStringHydrator,
private requestContextCache: RequestContextCacheService,
) {}

@ResolveField()
name(@Ctx() ctx: RequestContext, @Parent() facetValue: FacetValue): Promise<string> {
Expand All @@ -21,6 +26,8 @@ export class FacetValueEntityResolver {
if (facetValue.facet) {
return facetValue.facet;
}
return this.facetService.findByFacetValueId(ctx, facetValue.id);
return this.requestContextCache.get(ctx, `FacetValueEntityResolver.facet(${facetValue.id})`, () =>
this.facetService.findByFacetValueId(ctx, facetValue.id),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export class ProductEntityResolver {
@Ctx() ctx: RequestContext,
@Parent() product: Product,
): Promise<Array<Translated<ProductOptionGroup>>> {
const a = info;
return this.productOptionGroupService.getOptionGroupsByProductId(ctx, product.id);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { Permission } from '@vendure/common/lib/generated-types';

import { RequestContextCacheService } from '../../../cache/request-context-cache.service';
import { Translated } from '../../../common/types/locale-types';
import { assertFound } from '../../../common/utils';
import { ProductOptionGroup } from '../../../entity/product-option-group/product-option-group.entity';
Expand All @@ -16,6 +17,7 @@ export class ProductOptionEntityResolver {
constructor(
private productOptionGroupService: ProductOptionGroupService,
private localeStringHydrator: LocaleStringHydrator,
private requestContextCache: RequestContextCacheService,
) {}

@ResolveField()
Expand All @@ -32,6 +34,8 @@ export class ProductOptionEntityResolver {
if (option.group) {
return option.group;
}
return assertFound(this.productOptionGroupService.findOne(ctx, option.groupId));
return this.requestContextCache.get(ctx, `ProductOptionEntityResolver.group(${option.groupId})`, () =>
assertFound(this.productOptionGroupService.findOne(ctx, option.groupId)),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CurrencyCode, StockMovementListOptions } from '@vendure/common/lib/gene
import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
import { PaginatedList } from '@vendure/common/lib/shared-types';

import { RequestContextCacheService } from '../../../cache/request-context-cache.service';
import { Translated } from '../../../common/types/locale-types';
import { idsAreEqual } from '../../../common/utils';
import { Asset, Channel, FacetValue, Product, ProductOption, TaxRate } from '../../../entity';
Expand All @@ -23,6 +24,7 @@ export class ProductVariantEntityResolver {
private productVariantService: ProductVariantService,
private assetService: AssetService,
private localeStringHydrator: LocaleStringHydrator,
private requestContextCache: RequestContextCacheService,
) {}

@ResolveField()
Expand Down Expand Up @@ -67,7 +69,11 @@ export class ProductVariantEntityResolver {
if (productVariant.product) {
return productVariant.product;
}
return this.productVariantService.getProductForVariant(ctx, productVariant);
return this.requestContextCache.get(
ctx,
`ProductVariantEntityResolver.product(${productVariant.productId})`,
() => this.productVariantService.getProductForVariant(ctx, productVariant),
);
}

@ResolveField()
Expand Down

0 comments on commit 13697c3

Please sign in to comment.