From 68b7717c78a133fcb54318785e39b9d1239cb32e Mon Sep 17 00:00:00 2001 From: Jaden VanEckhout Date: Thu, 17 Feb 2022 21:27:17 -0600 Subject: [PATCH] feat(nextjs-cdk-construct): allow cache policies to be provided as props (#2350) --- documentation/docs/cdkconstruct.md | 3 + .../__tests__/construct.test.ts | 62 ++++++++++++++++++- .../nextjs-cdk-construct/src/index.ts | 21 +++---- .../nextjs-cdk-construct/src/props.ts | 18 +++++- 4 files changed, 90 insertions(+), 14 deletions(-) diff --git a/documentation/docs/cdkconstruct.md b/documentation/docs/cdkconstruct.md index 154ecbcafc..db7ed7a70d 100644 --- a/documentation/docs/cdkconstruct.md +++ b/documentation/docs/cdkconstruct.md @@ -101,3 +101,6 @@ new NextJSLambdaEdge(this, "NextJsApp", { - `invalidationPaths?: string[]` - an array of invalidation paths, by default we invalidate all pages found in manifest - `cachePolicyName?: Object`: configure the name given to the cache policies +- `nextStaticsCachePolicy?: CachePolicy;`: configure the CloudFront cache policy used for static resources +- `nextImageCachePolicy?: CachePolicy;`: configure the CloudFront cache policy used for image caching +- `nextLambdaCachePolicy?: CachePolicy;`: configure the CloudFront cache policy used for Lambda functions diff --git a/packages/serverless-components/nextjs-cdk-construct/__tests__/construct.test.ts b/packages/serverless-components/nextjs-cdk-construct/__tests__/construct.test.ts index 9deddd032c..41eb6891aa 100644 --- a/packages/serverless-components/nextjs-cdk-construct/__tests__/construct.test.ts +++ b/packages/serverless-components/nextjs-cdk-construct/__tests__/construct.test.ts @@ -6,7 +6,7 @@ import { NextJSLambdaEdge } from "../src"; import { Runtime, Function, Code } from "aws-cdk-lib/aws-lambda"; import { Certificate } from "aws-cdk-lib/aws-certificatemanager"; import { HostedZone } from "aws-cdk-lib/aws-route53"; -import { LambdaEdgeEventType } from "aws-cdk-lib/aws-cloudfront"; +import { LambdaEdgeEventType, CachePolicy } from "aws-cdk-lib/aws-cloudfront"; describe("CDK Construct", () => { it("passes correct lambda options to underlying lambdas when single value passed", () => { @@ -146,6 +146,66 @@ describe("CDK Construct", () => { ); }); + it("statics cache policy uses passed in policy if provided", () => { + const stack = new Stack(); + new NextJSLambdaEdge(stack, "Stack", { + serverlessBuildOutDir: path.join(__dirname, "fixtures/app"), + nextStaticsCachePolicy: new CachePolicy(stack, "NextStaticsCache", { + cachePolicyName: "customNextStaticsCache" + }) + }); + + const synthesizedStack = SynthUtils.toCloudFormation(stack); + expect(synthesizedStack).toHaveResourceLike( + "AWS::CloudFront::CachePolicy", + { + CachePolicyConfig: { + Name: "customNextStaticsCache" + } + } + ); + }); + + it("image cache policy uses passed in policy if provided", () => { + const stack = new Stack(); + new NextJSLambdaEdge(stack, "Stack", { + serverlessBuildOutDir: path.join(__dirname, "fixtures/app"), + nextImageCachePolicy: new CachePolicy(stack, "NextImageCache", { + cachePolicyName: "customNextImageCache" + }) + }); + + const synthesizedStack = SynthUtils.toCloudFormation(stack); + expect(synthesizedStack).toHaveResourceLike( + "AWS::CloudFront::CachePolicy", + { + CachePolicyConfig: { + Name: "customNextImageCache" + } + } + ); + }); + + it("lambda cache policy uses passed in policy if provided", () => { + const stack = new Stack(); + new NextJSLambdaEdge(stack, "Stack", { + serverlessBuildOutDir: path.join(__dirname, "fixtures/app"), + nextLambdaCachePolicy: new CachePolicy(stack, "NextLambdaCache", { + cachePolicyName: "customNextLambdaCache" + }) + }); + + const synthesizedStack = SynthUtils.toCloudFormation(stack); + expect(synthesizedStack).toHaveResourceLike( + "AWS::CloudFront::CachePolicy", + { + CachePolicyConfig: { + Name: "customNextLambdaCache" + } + } + ); + }); + it("creates resources required for a custom domain when specified", () => { const stack = new Stack(); const certificate = Certificate.fromCertificateArn( diff --git a/packages/serverless-components/nextjs-cdk-construct/src/index.ts b/packages/serverless-components/nextjs-cdk-construct/src/index.ts index 549fb63279..5c901adf72 100644 --- a/packages/serverless-components/nextjs-cdk-construct/src/index.ts +++ b/packages/serverless-components/nextjs-cdk-construct/src/index.ts @@ -233,10 +233,9 @@ export class NextJSLambdaEdge extends Construct { this.nextImageLambda.currentVersion.addAlias("live"); } - this.nextStaticsCachePolicy = new cloudfront.CachePolicy( - this, - "NextStaticsCache", - { + this.nextStaticsCachePolicy = + props.nextStaticsCachePolicy || + new cloudfront.CachePolicy(this, "NextStaticsCache", { cachePolicyName: props.cachePolicyName?.staticsCache, queryStringBehavior: cloudfront.CacheQueryStringBehavior.none(), headerBehavior: cloudfront.CacheHeaderBehavior.none(), @@ -249,10 +248,9 @@ export class NextJSLambdaEdge extends Construct { } ); - this.nextImageCachePolicy = new cloudfront.CachePolicy( - this, - "NextImageCache", - { + this.nextImageCachePolicy = + props.nextImageCachePolicy || + new cloudfront.CachePolicy(this, "NextImageCache", { cachePolicyName: props.cachePolicyName?.imageCache, queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(), headerBehavior: cloudfront.CacheHeaderBehavior.allowList("Accept"), @@ -265,10 +263,9 @@ export class NextJSLambdaEdge extends Construct { } ); - this.nextLambdaCachePolicy = new cloudfront.CachePolicy( - this, - "NextLambdaCache", - { + this.nextLambdaCachePolicy = + props.nextLambdaCachePolicy || + new cloudfront.CachePolicy(this, "NextLambdaCache", { cachePolicyName: props.cachePolicyName?.lambdaCache, queryStringBehavior: cloudfront.CacheQueryStringBehavior.all(), headerBehavior: props.whiteListedHeaders diff --git a/packages/serverless-components/nextjs-cdk-construct/src/props.ts b/packages/serverless-components/nextjs-cdk-construct/src/props.ts index c22bbc0521..cfcc8fb59a 100644 --- a/packages/serverless-components/nextjs-cdk-construct/src/props.ts +++ b/packages/serverless-components/nextjs-cdk-construct/src/props.ts @@ -1,5 +1,5 @@ import { ICertificate } from "aws-cdk-lib/aws-certificatemanager"; -import { BehaviorOptions, DistributionProps } from "aws-cdk-lib/aws-cloudfront"; +import { BehaviorOptions, DistributionProps, CachePolicy } from "aws-cdk-lib/aws-cloudfront"; import { Runtime } from "aws-cdk-lib/aws-lambda"; import { IHostedZone } from "aws-cdk-lib/aws-route53"; import { BucketProps } from "aws-cdk-lib/aws-s3"; @@ -108,4 +108,20 @@ export interface Props extends StackProps { * Override props passed to the underlying s3 bucket */ cloudfrontProps?: Partial; + + /** + * Override cache policy used for statics + */ + nextStaticsCachePolicy?: CachePolicy; + + /** + * Override cache policy used for image caching + */ + + nextImageCachePolicy?: CachePolicy; + + /** + * Override cache policy used for Lambda + */ + nextLambdaCachePolicy?: CachePolicy; }