How to use selectively choose the lambda version for an APIG API at runtime? - aws-lambda

I have a use case where an API backed by a lambda has to be latency critical for a few clients but there are clients how call the API with high volume in bursts and the latency restrictions are liberal .
We are using provisioned concurrency for the latency critical calls and do not want to use it for non latency critical calls as the cost is high.
Since provisioned concurrency can only be used with alias/version, is it possible to choose the lambda version at runtime based on the API Key?
Determine the client based on the API Key and point to the appropriate version. I am trying to avoid creating 2 API endpoints one for latency critical clients and the other for non-latency critical clients.

It is not possible for API Gateway to invoke a Lambda function alias based on the API key passed in the request. What you can do is set up 2 API Gateway stages, one for latency critical calls and the other for non-critical ones. Now, the Lambda function integration would need to be set up to use API GW stage variables so the appropriate Lambda function alias can be invoked based on the stage. You can refer to this blog post on how to configure that: https://docs.aws.amazon.com/apigateway/latest/developerguide/stages.html
So, using this method, you would be creating two endpoints, but the API configuration for both would be similar.

Related

Dynamic HTTP request routing using rules implemented in AWS Lambda

I would like to use a Lambda function to implement dynamic routing rules for HTTP requests targeted at a fleet of Fargates. I need the Lambda function because routing rules require dynamic lookups to be made on an external database service (Redis cluster in this case).
Is there a way to do that using Elastic Load Balancing or API Gateway?
Is thee any other option that I should consider?
There is no way to have a Lambda function be part of the routing logic of either of those services. This would have to be something that you created yourself.
Each of the Lambda functions would have to know about the endpoints of the targets and when to send traffic there.

https calls from multiple lambda functions

I am learning AWS lambda and have a basic question regarding architecture with respect to managing https calls from multiple lambda functions to a single external service.
The external service will only process 3 requests per second from any IP address. Since I have multiple asynchronous lambdas I cannot be sure I will be below this threshold. I also don't know what IPs my lambdas use or even if they are the same or not.
How should this be managed?
I was thinking of using an SQS FIFO queue, but I would need to setup a bidirectional system to get the call responses back to the appropriate lambda. I think there must be a simple solution to this, but I'm just not familiar enough yet.
What would you experts suggest?
If I am understanding your question correctly then
You can create and API Endpoint by build an API Gateway with Lambda integrations(preferred Lambda proxy integration) and then use throttling option to decide the throughput this can be done in different ways aws docs account level, method level etc.
You can perform some load testing using gatling or any other tool and then generate a report for eg. which can show that even if you have say 6tps on your site you can throttle at method level and see that the external service is hit only at say 3tps.
It would depend upon your architecture how do you want to throttle I had done method level to protect the external service at 8tps.

Serverless - Running an Express instance in a Lambda function, good or bad?

While learning the Serverless Framework I came across several tutorials showing how to run an Express instance in a Lambda. This seems to me like an overkill and against the purpose of Lambda functions.
The approach usually involves running an Express instance in the Lambda and proxying API Gateway requests to the Express router for internal handling.
To me the trivial approach is to just create an API in API Gateway and route individual requests to a Lambda for handling. Am I missing something?
Taking into account that Lambdas' execution time is 15 minutes, isn't just spinning up the Express instance quite expensive in terms of memory? Also, limited to 100 concurrent Lambda executions would create a bottleneck, no? Wouldn't an EC2 instance be a better fit in such case? Using a Lambda like this seems like an overkill.
The only two benefits I see in running an Express instance in a Lambda are:
In the case of migration of an existing app written in Express, allows to slowly break down the app into API Gateway endpoints.
Internal handling of routing rather than relying on the API Gateway request/response model (proxying to Express router).
What would be the benefit of such approach, in case I am missing something?
Some resources promoting this approach:
Express.js and AWS Lambda — a serverless love story (Slobodan Stojanović, freeCodeCamp)
awslabs/aws-serverless-express (GitHub)
Deploy a REST API using Serverless, Express and Node.js (Alex DeBrie, Serverless Framework Blog)
Most of your points are valid, and it can indeed be called an antipattern to run Express inside your Lambda functions behind an API Gateway.
Should be noted that the initialization time is not that much of a concern. While the execution time of a single invocation is capped at 15 minutes, a single Lambda instance will serve multiple requests after it has been fired up. A frequently invoked single Lambda instance has usually a lifetime or 6 to 9 hours, and is disposed of at about 30 minutes of inactivity. (note that AWS does not publicly disclose these parameters and these figures should only be used as a ballpark). Whoever is the unlucky one to get the cold start and eat the initialization delay could get an additional delay in the thousands of milliseconds however.
The singular main advantage of this approach is, as you said, providing a migration path for existing Node developers with existing Express knowledge and applications. You should generally not consider this approach when developing an application from scratch and implement idiomatic serverless patterns instead (e.g. utilizing API Gateway routing).
Just to reiterate, the main downsides of this approach:
Higher needless overall code complexity due to forgoing API Gateway functionality (routing etc.)
Higher initialization time resulting in longer cold starts
Larger code footprint due to more dependencies
Larger code footprint due to losing tree shaking / individual packaging due to internal routing
P.S. The main contender these days probably wouldn't be a dedicated EC2 instance, and rather Fargate containers running Express in Node.js. This pattern has many of the same benefits as Serverless while keeping existing development patterns and tools largely intact.

Should a microservice take care of this or the api gateway?

I am building out a microservice architecture and kinda confused on one part. I am using Kafka as a message broker system to communicate within my services. A perfect example would be Uber's API for request estimation. It returns duration, distance, price, etc. I would assume they have a microservice for each of those, i.e. service for pricing, service for duration/distance, service for drivers, etc. My question is when hitting the endpoint /requests/estimate does the requests microservice make rest calls to the other microservices to retrieve data for the duration, distance, etc? or does the API Gateway take care of that?
I say it depends on the use case. If service A needs to know what service B knows, then it is perfectly sane for service A to make a REST call to service B. But if the combined knowledge for A and B is only needed in your gateway then the gateway can combine the results.
Both are perfectly valid ways of doing it, but I would go the Estimate microservice way to avoid putting too much logic in the API Gateway.
Maybe in the future your estimation calculation will change, and it wouldn't make much sense to me to update the gateway every time.
In practice, not all gateway APIs support multiple calls and aggregation. In the micro service architecture, there is a common pattern ("API Composition", "Composition Patterns" in particular "Aggregator Pattern"), the idea of which is that you need to make a separate service that will contain the business logic of multiple calls and aggregation.

Backends For Frontends BFFs or API Gateway

In a micro-services architecture we can have:
A single API gateway providing a single API for all clients.
A single API gateway providing an API for each kind of client.
A per-client API gateway providing each client with an API. which is the BFF pattern.
Netflix uses the second style Inside the Netflix API Redesign. we can surely say that they have created a smart-piece of middleware in their architecture that takes on multiple responsibilities.
But how much work this single API back-end can handle, it seems that it can become a bottleneck so easily.
So my question is what are the benefits of choosing the single API to handle requests for more than 1000 clients instead of creating an API Gateway specifically designed to one type of clients? Aren't they facing many challenges to manage and maintain this complex piece?
It all depends where your end users are, in case of Netflix, they have differnt types of clients, web/mobile/streaming sticks/bluray players/what not, while web (updated to latest all the time), mobile (updated to latest eventually), bluray player with pre-installed app for example may never get updated.
And you have to version your apis accordingly for each platform and maintain them based on client update cycle for backward compatibility. If you have too many variations in a single api it will be hard to maintain instead it is easier to write an api for each type of client. Unless you have real need for #3 and have enough resources to develop for each type of client I wouldn't jump into it, as you have to maintain many variations of api for the same purpose.
I would start small with #1.

Resources