Serverless Caching Strategies - Part 1 (Amazon API Gateway) 🚀

How to use serverless caching strategies within your solutions, with code examples and visuals, written in TypeScript and the CDK, and with associated code repository in GitHub. Part 1 covering Amazon API Gateway.

--

Introduction

This is Part 1 of a number of articles covering serverless caching strategies on AWS, and why you should use them. This first part will be a high level introduction to caching, and examples in TypeScript and the CDK for caching with Amazon API Gateway.

🔵 Part 2 of this article looks at caching at the database level using DynamoDB DAX.

🔵 Part 3 of this article will look at caching within the Lambda runtime environment itself.

🔵 Part 4 of this article will look at caching at the AppSync level.

🔵 Part 5 of this article will look at caching at the CDN level with CloudFront.

What is caching, and why use it? ☁️

Let’s start by covering ‘What is caching?’. In computing, a cache is a high-speed data storage layer which stores a subset of data, typically transient in nature, so that future requests for that data are served up faster than is possible by accessing the data’s primary storage location. Caching allows you to efficiently reuse previously retrieved or computed data.

In computing, a cache is a high-speed data storage layer which stores a subset of data, typically transient in nature, so that future requests for that data are served up faster than is possible by accessing the data’s primary storage location. Caching allows you to efficiently reuse previously retrieved or computed data. — https://aws.amazon.com/caching/

The data in a cache is generally stored in fast access hardware such as RAM (Random-access memory) and may also be used in correlation with a software component. A cache’s primary purpose is to increase data retrieval performance by reducing the need to access the underlying slower storage layer.

Trading off capacity for speed, a cache typically stores a subset of data transiently, in contrast to databases whose data is usually complete and durable.

Why use caching?

The main benefit of caching in Serverless applications is increased speed, which in turn can also have the added benefit of reduced costs.

Within serverless applications caching typically means faster API response times, faster page load speeds, reduced latency, faster query speeds etc. This can also lead to a reduction in both compute and database calls, which in turn can reduce costs as an added benefit.

When should I think about caching?

I covered this in a previous article linked below, where I discussed Serverless TACTICAL DD(R) as an approach to non functional requirements, Definition of Ready and Definition of Done; which in turn can help you think about caching strategies at the right time in the SDLC:

What are we building over the series? 🏗️

Over the series of articles we are going to build two fictitious blogs, one specifically for Serverless articles, and the other for AWS News. You can see the high level architectures below and a detailed walkthrough of it (pink circles indicating where you could possibly cache in these solutions):

Serverless Blog ✔️

The serverless blog has the following flow:

⚪ A CloudFront distribution caches the React website which has an S3 bucket as its origin. We can cache the web app at this level.

⚪ The React app utilises a GraphQL API for accessing its data using AWS AppSync. For certain endpoints we may look to utilise AppSync caching.

⚪ The AppSync API resolves to DynamoDB through Lambda for its data, and we are using DAX as a cache sitting in front of the database. We can utilise DAX to cache at the database level here.

AWS News Blog ✔️

The AWS News blog has the following flow:

⚪ A CloudFront distribution caches the React website which has an S3 bucket as its origin. We can cache the web app at this level.

⚪ The React app utilises a REST API for its data using Amazon API Gateway. We have caching here at the API level within API Gateway.

⚪ For cache misses we use a Lambda function to retrieve the data from a Serverless Aurora database. We can also cache certain data within the lambda itself in this scenario.

💡 Note: this is the minimal code and architecture to allow us to discuss key architecture points in the article, so this is not production ready and does not adhere to coding best practices. (For example no authentication on end points). I have also tried not to split out the code too much so example files are easy to view with all dependencies in one file.

Where can we cache on AWS? ☁️

The following diagram shows some of the layers of our architecture that we can enable caching strategies in.

When it comes to caching on AWS I personally like to cache as close to the consumer as possible, for example:

What services are we going to use across the series of articles? 🧰

The list below goes into more detail regarding the services which we are going to use in this series, but feel free to skip to the next section if you have used them before:

Feel free to skip to the next section ‘What are we building?’ if you are comfortable with the majority of the AWS services and just want to see the architecture pattern.

Amazon DynamoDB Accelerator (DAX) ✔️

Amazon DynamoDB Accelerator (DAX) is a fully managed, highly available, in-memory cache for Amazon DynamoDB that delivers up to a 10 times performance improvement — from milliseconds to microseconds — even at millions of requests per second.

DAX does all the heavy lifting required to add in-memory acceleration to your DynamoDB tables, without requiring developers to manage cache invalidation, data population, or cluster management.

Now you can focus on building great applications for your customers without worrying about performance at scale. You do not need to modify application logic because DAX is compatible with existing DynamoDB API calls. Learn more in the DynamoDB Developer Guide.

https://aws.amazon.com/dynamodb/dax/

Amazon CloudFront ✔️

Amazon CloudFront is a content delivery network (CDN) service built for high performance, security, and developer convenience.

Reach viewers across the globe in milliseconds with built-in data compression, edge compute capabilities, and field-level encryption.

AWS AppSync ✔️

Organisations choose to build APIs with GraphQL because it helps them develop applications faster, by giving front-end developers the ability to query multiple databases, microservices, and APIs with a single GraphQL endpoint.

AWS AppSync is a fully managed service that makes it easy to develop GraphQL APIs by handling the heavy lifting of securely connecting to data sources like AWS DynamoDB, Lambda, and more. Adding caches to improve performance, subscriptions to support real-time updates, and client-side data stores that keep off-line clients in sync are just as easy. Once deployed, AWS AppSync automatically scales your GraphQL API execution engine up and down to meet API request volumes.

💡 Note: AppSync also has built in caching which we won’t be covering in this article.

https://aws.amazon.com/appsync/

Amazon API Gateway ✔️

Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the “front door” for applications to access data, business logic, or functionality from your backend services. Using API Gateway, you can create RESTful APIs and WebSocket APIs that enable real-time two-way communication applications. API Gateway supports containerised and serverless workloads, as well as web applications.

💡 Note: API Gateway also has built in caching

Getting Started! ✔️

To get started, clone the following repo with the following git command:

git clone https://github.com/leegilmorecode/serverless-caching

This will pull down the example code to your local machine.

Deploying the solution! 👨‍💻

🛑 Note: Running the following commands will incur charges on your AWS accounts, and some services are not in free tier.

In the ‘aws-blog’ folder of the repo run the following command to install all of the dependencies:

npm i

Once you have done this, run the following command to deploy the solution:

npm run deploy

🛑 Note: Remember to tear down the stack when you are finished so you won’t continue to be charged, by using ‘npm run remove’.

💡 Note: We use a CustomResource as part of the deploy to create the blogs table and populate it with some dummy data, so you can use it straight away.

Testing the solution 🎯

Now that we have the solution deployed, you can test the endpoints using the postman file which can be found here: aws-blog/postman/serverless-caching-aws-blogs.postman_collection.json

Example response from the API

Talking through key code 👊

OK, so we have discussed what caching is, where we can perform it with API Gateway, and how to deploy the example repo — now let’s look through some code.

The following snip-it from the repo shows how we setup API Gateway using the CDK, and the relevant caching for the two distinct methods, where we can override the default settings for each at a finer level:

The code above shows that for the /Blogs GET we have set caching to be enabled, and it will cache the response for 10 minutes. As our blog doesn’t change a lot this seems a sensible value to set.

For the /Blogs/{id} GET we need to setup our cache key parameters based on the id in the path, otherwise all of the blogs/1, blogs/2 calls etc will all cache and return the same data! (which we obviously don’t want!) We can see this in the code below:

In the code for the lambdas themselves we are also returning a property called ‘responseDateTime’ so we easily see the caching in action. This is shown below in the GIF where we can see the initial request sets the time portion of the DTO too ‘14:00:51’ from ‘13:59:24’, and it remains at the ‘14:00:51’ timestamp for subsequent calls as the response is cached (the request latency on average goes from 250ms to 50ms with caching in place):

Example of the caching taking place

We can also look at the API Gateway CloudWatch metrics to see the cache hits in action across the four variations of the endpoints (the cache misses are the first requests being made):

And looking at the CloudWatch logs for the get-blog lambda we can see the caching taking place, and that there is only one entry for each of the blog ID requests, regardless of hitting the endpoints many, many times (this is because the caching at the API level means that cache hits never hit our lambdas, or therefore database too):

Example logs showing lambda not invoked when caching taking place at the API

Summary

I hope you found that useful! Join me in Part 2 where we continue to look at caching at the database level using DynamoDB DAX.

Go and subscribe to my Enterprise Serverless Newsletter here for more of the same content:

Wrapping up 👋

Please go and subscribe on my YouTube channel for similar content!

I would love to connect with you also on any of the following:

https://www.linkedin.com/in/lee-james-gilmore/
https://twitter.com/LeeJamesGilmore

If you found the articles inspiring or useful please feel free to support me with a virtual coffee https://www.buymeacoffee.com/leegilmore and either way lets connect and chat! ☕️

If you enjoyed the posts please follow my profile Lee James Gilmore for further posts/series, and don’t forget to connect and say Hi 👋

Please also use the ‘clap’ feature at the bottom of the post if you enjoyed it! (You can clap more than once!!)

This article is sponsored by Sedai.io

About me

Hi, I’m Lee, an AWS Community Builder, Blogger, AWS certified cloud architect and Principal Software Engineer based in the UK; currently working as a Technical Cloud Architect and Principal Serverless Developer, having worked primarily in full-stack JavaScript on AWS for the past 5 years.

I consider myself a serverless advocate with a love of all things AWS, innovation, software architecture and technology.

*** The information provided are my own personal views and I accept no responsibility on the use of the information. ***

You may also be interested in the following:

--

--

Global Head of Technology & Architecture | Serverless Advocate | Mentor | Blogger | AWS x 7 Certified 🚀