12
votes

I'm a bit confused by how API Gateway and CloudFront work together. Ultimately, I want to be able to have a custom header and value be considered part of my cache key. I know this can be done by whitelisting (if I'm using CloudFront).

So when I make the following request:

GET /pagesRead/4
Some-Header: fizz

This returns, for instance, '29 pages'

Then there's a post that updates id 4 to '45 pages'

If I make this request

GET /pagesRead/4
Some-Header: buzz

It will now return '45 pages'

But I'm using API Gateway, which obviously has it's own CloudFront behind the scenes. Is there a way I can configure API Gateway to use its 'behind-the-scenes' CloudFront to whitelist my custom header? Does this even need to be done?

According to this documentation: AWS-API-Gatway, It seems like I can just enable API caching in API Gateway, and it will consider my headers as part of the cache key.

Am I understanding this correctly? If all I want is for my headers to be a part of the cache key, what's the difference between 'Enabling API Caching' in API Gateway and adding a CloudFront instance on top of API Gateway and white-listing in CloudFront?

UPDATE:

I've added a header like this in API Gateway: enter image description here

But on GET, I am getting stale data from the cache.

GET /pagesRead/4 test-header: buzz
2

2 Answers

11
votes

The difference is that API Gateway doesn't actually use the CloudFront cache. CloudFront does provide some front-end services for all API Gateway APIs edge-optimized API endpoints¹, but caching does not appear to be one of them, based on the following:

API Gateway enables caching by creating a dedicated cache instance.

...and...

You should not use the X-Cache header from the CloudFront response to determine if your API is being served from your API Gateway cache instance.

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html

It is possible to cascade an Edge Optimized API Gateway endpoint behind a CloudFront distribution that you create, but it's not without certain inconveniences. Latency increases somewhat, since you're passing through more systems. Given that configuration, the CloudFront-Is-*-Viewer and CloudFront-Viewer-Country headers, and probably any notion of the client IP will be invalid, because the API Gateway deployment will see attributes of the additional CloudFront distribution that is in front of it, rather than of the real client. X-Forwarded-For will still be right, but will have to be handled with care, because it will contain one extra hop that will have to be correctly handled.

For an application where you want to put API Gateway behind your own CloudFront distribution, use one of the new Regional endpoints to deploy your API stage.

it will consider my headers as part of the cache key.

You do have to configure the cache key explicitly, based on the document you cited, but yes, the API Gateway cache will then cache responses based on the value of that header, and other attributes in the cache key.


¹ edge optimized endpoints. API Gateway now has two different kinds of endpoints. The original design is now called edge-optimized, and the new option is called regional. Regional endpoints do not use front-end services from CloudFront, and may offer lower latency when accessed from EC2 within the same AWS region. All existing endpoints were categorized as edge-optimized when the new regional capability was rolled out. With a regional endpoint, the CloudFront-* headers are not present in the request, unless you use your own CloudFront distribution and whitelist those headers for forwarding to the origin.

1
votes

When you enable caching in API Gateway,

You can also optionally add,

RequestPath
QueryStringParameters
Http Headers

E.g.,

http://example.com/api/{feature}/?queryparam=queryanswer [ with header customheader=value1 ]

Above url gives you option to cache based on,

Just the URL without PathParameters: http://example.com/api/

Optionally include PathParameter: http://example.com/api/{feature}/

Optionally include QueryStrings: http://example.com/api/{feature}/?queryparam=queryanswer

Optionally include Http Headers: You can either include regular header like User-Agent or Custom headers

Whatever the caching mode you have in API-Gateway, you can also have it under CloudFront as well.

Also to clear up the cache, in your http response send Cache-Control: max-age=0

Hope it helps.

CloudFront cache image