AWS API Gateway + Lambda Proxy Integration Cache Issues - amazon-web-services

I am trying to set-up API Gateway + Lambda Proxy + Cache and having issues with it.
Firstly it doesn't seem to be hitting the cache. Oddly when I use chrome dev tools to hit it and click 'disable' cache, it somehow does hit the cache! The difference is it sets the cache-control to 'none'. A normal requests it sets cache-control to 'max-age=0'.
Secondly when it does cache, its ignoring the URL parameter as a key so with different querystring values, it still returns the same response.
I have enabled the API Cache on the stage settings, I have also entered the 'querystrings' in the Method request settings as well and turned on the 'caching' checkbox for each querystring parameter.
Any thoughts on this? If this does not work I may have to resort to using Elasticache internally but it would have been great if API Gateway could handle this directly.
My API request are 'GET' requests with querystring parameters.

Related

Google Cloud CDN - cache based on request body, not url

I need to support legacy API, which have constant url and request is differentiate using xml body. Is there any option to use body as cache KEY in Google CDN?
If no, I'm thinking about rewriting requests to add based64 body in url, what do you think about that?
No, Google Cloud CDN does not support using the request body as part of the cache key. Moving the relevant information to the URL would work, but only if the HTTP method is GET or HEAD. (Google Cloud CDN never serves cached content in response to other HTTP methods such as POST.)
There's more information on cache keys at https://cloud.google.com/cdn/docs/caching#cache-keys.

How to get past CloudFront cached redirect and hit API Gateway instead?

I have a CloudFront distribution set up so that <domain>/api redirects me to <api-gateway-url>/<env>/api. However I find that sometimes CloudFront caches responses to GET requests and the browser does not redirect to the API Gateway endpoint and returns the cached response.
Example: /api/getNumber redirects to <api-gateway-url>/<env>/api/getNumber and returns me 2. I change the response so that it should return the number 300, but when I make a request through my browser now there is no redirect and I still get back the number two. The x-cache response header says cache hit from CloudFront.
AWS CloudFront is often used for caching, thus decreasing the number of requests that will hit the back-end resources. Therefore you shouldn't use CloudFront on your testing environment if you want to imediately see changes.
In your case it seems, that your endpoint doesn't have any parameters (Path/Query), so essentially what CloudFront sees is the same request every time, naturally in this case you will hit the cache.
You have a couple of options to "fix" that:
Diversify your API requests (using parameters for example)
Use CloudFront's TTL options, to make CloudFront keep the cached objects less time
NOTE: This is not advisable if this is production environment, because it might eliminate the whole point of caching and disrupt expected behavior
Disable CloudFront's caching for those paths that don't take parameters and/or whose response will change often, thus keeping caching on for the rest of your distribution:
https://aws.amazon.com/premiumsupport/knowledge-center/prevent-cloudfront-from-caching-files/
And lastly if this is just your test environment, disable CloudFront, but the things above might later on apply to your production environment

AWS nginx as a service?

I'm looking for a service that allows me to proxy/modify incoming requests inside AWS.
Currently I am using cloudfront, but that has limited functions.
I need to be able to see user agent strings and make proxy decisions based on that - like reverse proxying to another domain, or routing all requests to /index.html.
Anyone know of a service that within AWS - or outside of AWS.
It sounds like you are describing Lambda#Edge, which is a CloudFront enhancement that allows you to define Lambda functions that will fire at any of 4 hook points in the CloudFront signal flow, and modify the request or generate a dynamic response.
Viewer Request triggers allow inspection/modification of requests and dynamic generation of small responses before the cache lookup.
Origin Request triggers are similar, but fire after the cache is checked. They allow you to inspect and modify the request, including changing the origin server, path, and/or query string, or to generate a response instead of allowing CloudFront to proceed with the connection to the origin.
If the request goes to the origin, then once it returns, an Origin Response trigger can fire to modify the response headers or replace the response body with a different body you generate. The response after this trigger is finished with it is what gets stored in the cache, if cacheable.
Once a reaponse is cached, further firing of the Origin Request and Origin Response triggers doesn't occur for subsequent requests that can be served from the cache.
Finally, when the response is ready, whether it came from the cache or the origin, a Viewer Response trigger can modify it further, if desired.
Response triggers can also inspect many of the headers from the original request.
Lambda#Edge functions are written in Node.js, and are presented with the request or responses as simple structured objects that you inspect and/or modify.

Prevent caching of non 200 responses in AWS API Gateway

How should I go about disabling the cache of non 200 OK responses in API Gateway.
For one of our API endpoints we implemented our complementary throttle mechanism and we're sending a 429 HTTP response.
The intention is for the client to retry the request after a short time when the server is ready to fulfil it but what happens now is that the API Gateway caches the initial response and keeps sending that from cache instead.
As per the response to Can AWS API Gateway cache invalidate specific entries based on the response content?, the API Gateway cache doesn't appear to have the functionality to just "sometimes" cache a result. The documentation shows a way to have the client make a request that will ignore the existing cache (by setting Cache-Control: max-age=0), but doesn't show a way for the server to say that "this is a single-use response that shouldn't be cached.
The first thing that I think is worth trying is specifying a header like Cache-Control: max-age=0 in your error response just to try it to see if it works. The AWS API Gateway uses CloudFront under the hood for its distribution, so it may just work.
If that doesn't work, other options include:
Turn off the AWS API Gateway cache. If you need a cache, set up your own caching using CloudFront or another service that allows for more fine-grained control over which responses get cached.
Try to move your throttling earlier in the process (I'm not sure if you're using the built-in API Throttling features), but since you've said you "implemented" your mechanism I'm guessing you are doing it yourself in your back-end handling the requests. If you can do throttling before your caching layer (whether it's the built-in API Gateway caching or some other system), that may end up solving your problem and put less strain on your back-end request handler.
After sending 429 responses to the client, when the service is free to handle further requests, send your own "cache invalidation" request with Cache-Control: max-age=0 to get the "real" value cached. Obviously, this would be a bit tricky as you'd need to know when the service is up and available to handle more requests without getting bogged down again with adding a bunch more requests as soon as it's "free" again.
Depending on your exact caching needs, just have a low-enough TTL in your caching settings. For example, if once throttling kicks in, it's likely to not be available again for at least 60 seconds, then having a 60 second TTL means that the 429 response will get served from the cache for that time. But, since you were just throttling anyway and thus your service is "overloaded", it may be acceptable for your situation to continue serving that 429 until the TTL expires. This would need to be the same short TTL for both "success" and "failure" responses, though.

Evaluate requests in the API Gateway

Can the API Gateway evaluate requests and route or return errors (not 200 statuses) on specific parameters?
What I want to achieve here is to NOT have millions of requests hitting our backend API since we already know (by evaluating the parameters) that we are not interested in returning responses on all requests but only a few percent.
I gave set up an API Proxy in the API Gateway with a complete set of requests, responses and backend.
The proxy is fully operational and up and running with throttling etc. What I would like is for the API Gateway to evaluate the requests querystring and depending on the values of certain parameters take different actions?
Let's say the complete URL and querystring is:
https://abc123.execute-api.eu-central-1.amazonaws.com/prod?param1=a&param2=b&param3=c
Now depending on the values of param1, param2 and param3 I might want to:
Forward the request to my actual API and return a response back to the client.
Drop the request OR return an empty (or templated) response with a specific HTTP-status (404, 503 etc - exact value not that important).
Is this achievable with the API Gateway or do I need to actually set up a host with a reverse proxy and let that handle this logic?
Request parameter and model validation has been a longstanding feature request and we are actively working on it. We'll update this post with more details when the feature has launched.
Update: Request parameter and body validation is now available as of early April 2017. see more details on this blog post.