I am very new to AWS Lambda and am struggling to understand its functionalities based on many examples I found online (+reading endless documentations). I understand the primary goal of using such service is to implement a serverless architecture that is cost and probably effort-efficient by allowing Lambda and the API Gateway to take on the role of managing your server (so serverless does not mean you don't use a server, but the architecture takes care of things for you). I organized my research into two general approaches taken by developers to deploy a Flask web application to Lambda:
Deploy the entire application to Lambda using zappa-and zappa configurations (json file) will be the API Gateway authentication.
Deploy only the function, the parsing blackbox that transforms user input to a form the backend endpoint is expecting (and backwards as well) -> Grab a proxy url from the API Gateway that configures Lambda proxy -> Have a separate application program that uses the url
(and then there's 3, which does not use the API Gateway and invokes the Lambda function in the application itself-but I really want to get a hands on experience using the API Gateway)
Here are the questions I have for each of the above two approaches:
For 1, I don't understand how Lambda is calling the functions in the Flask application. According to my understanding, Lambda only calls functions that have the parameters event and context-or are the url calls (url formulated by the API Gateway) actually the events calling the separate functions in the Flask application, thus enabling Lambda to function as a 'serverless' environment-this doesn't make sense to me because event, in most of the examples I analyzed, is the user input data. That means some of the functions in the application have no event and some do, which means Lambda somehow magically figures out what to do with different function calls?
I also know that Lambda does have limited capacity, so is this the best way? It seems to be the standard way of deploying a web application on Lambda.
For 2, I understand the steps leading to incorporating the API Gateway urls in the Flask application. The Flask application therefore will use the url to access the Lambda function and have HTTP endpoints for user access. HOWEVER, that means, if I have the Flask application on my local computer, the application will only be hosted when I run the application on my computer-I would like it to have persistent public access (hopefully). I read about AWS Cloud9-would this be a good solution? Where should I deploy the application itself to optimize this architecture-without using services that take away the architecture's severless-ness (like an EC2 instance maybe OR on S3, where I would be putting my frontend html files, and host a website)? Also, going back to 1 (sorry I am trying to organize my ideas in a coherent way, and it's not working too well), will the application run consistently as long as I leave the API Gateway endpoint open?
I don't know what's the best practice for deploying a Flask application using AWS Lambda and the API Gateway but based on my findings, the above two are most frequently used. It would be really helpful if you could answer my questions so I could actually start playing with AWS Lambda! Thank you! (+I did read all the Amazon documentations, and these are the final-remaining questions I have before I start experimenting:))
Zappa has its own code to handle requests and make them compatible with the "Flask" format. Keep in mind that you aren't really using Flask as intended in either cases when using Lambda. Lambdas are invoked only when calls are made, flask usually keeps running looking for requests. But the continuously running part is handled by the API Gateway here. Zappa essentially creates a single ANY request on API gateway, this request is passed to your lambda handler which interprets it and uses it to invoke your flask function.
If you you are building API Gateway + Lambda you don't need to use Flask. It would be much easier to simply make a function that is invoked by the parameters passed to lambda handler by the API Gateway. The front end application you can host on S3 (if it is static or Angular).
I would say the best practice here would be to not use Flask and go with the API Gateway + Lambda option. This lets you put custom security and checks on your APIs as well as making the application a lot more stable as every request has its own lambda.
Related
I’m trying to pick up API gateway.
What are the different use cases for alb vs API gateway? I’ll be honest to say that I am not completely familiar with the concept of an API. I know we can invoke it backend, and the analogy that it’s a restaurant menu. However, beyond that, I am not clear what the difference is. Is it that applications using ALB has a user interface, but not API gateway? I tried reading through documentation on the features, but got even more lost. As such, I am hoping someone can share the use cases for both services so that I can visualise what it’s used for and the reason for the features. Thanks!
API GW is focused on API and has some additional options - e.g. API definition via swagger, execution of a lambda function, converting the call to an event bridge event, support of authenticators (iam, cognito), multiple deployment stages etc.
The load balancer listens on a port and that's about it.
Q: In what cases would you require these API GW features as opposed to just using an ALB?
A: One obvious benefit is a serverless or "low code". Let's say you want an API which processes asynchronous requests.
It is possible to create an API endpoint which queues all incoming requests to a SQS queue with just one AWS CLI command with no programming (provided the resources do exist):
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services.html
Each API endpoint can be served by a different AWS resource including EC2/ALB.
ALB is well suited for things like traditional monolithic applications (LAMP, Java application servers etc.)
I have developed a simple microservice, REST based using Java 8 and Spring Boot2.0. It has its own REST end points which I can call using Postman and I get the response very well. Now I have doubt in understanding the design & architecture if I want to deploy the same application on AWS cloud. I want my application to behave as serverless so I want to deploy on AWS using its Lambda service.
Please assist to clear my following doubts :-
1) First, can I upload my whole application code to AWS Lambda in order to make it serverless?
2) If yes, then do I need to use AWS API Gateway (compulsorily) to invoke my Lambda function when the request passes through it?
3) If yes (point 2), then end points which are there in my original microservice code will become ineffective and will be overridden by new API Gateway end points?
My whole doubt is about end points, which end point will be used to invoke the Lambda functions?
Please assist to clarify my doubt. If there is any sample reference material then it will be really great.
Cheers
Spring Boot and AWS Lambda don't naturally go together IMO.
Lambda is pure code, it does not present itself as a HTTP Server, it is just triggered by one of the other AWS services (API Gateway, CloudWatch, S3, DynamoDB, Kinesis, SDK, etc.). The handler receives a JSON request from the calling service, and processes the request. Here is an example.
API Gateway does much of what Spring Boot provides for you. API Gateway is always online waiting for HTTP requests to come in, for which you only pay for incoming requests, you do not pay for idle (the definition of serverless IMO).
Once a request comes in, API Gateway wraps the request payload with some additional environmental data and sends it to your Lambda handler, which processes the request and returns some response to the client.
Saying that, if you don't want to restructure your service, there are a couple of options open to you:
Wrap into a Docker image and use an AWS Container Service, either using ECS or ElasticBeanstalk, neither of these are considered to be serverless.
I have not tried this, but according to AWS:
You can use the aws-serverless-java-container library to run a Spring Boot application in AWS Lambda. You can use the library within your Lambda handler to load your Spring Boot application and proxy events to it.
See links to Convert your SpringBoot project and Deploy it to AWS Lambda.
Hope this helps.
My use case is as follows,
I have built a rest api written in nodejs with serverless and when deployed will create lambdas and an api gateway that gives url which works fine. However, I will have multiple clients who would want to use this application (with their clients consuming the api) and I wouldn't want to duplicate the lambda's for each client as the business logic wouldn't change. What would be different is the stage variables set in the api gateway for each client.
Is there a way I can deploy and manage this using serverless, so that when a new client comes on board, I should be able to do something like update the serverless.yml with new api gateway details and then running the deploy command would generate the new gateway with it's own stage variables sharing the previously created lambdas.
Hope, the question is clear and apologies if this has been previously asked and answered.
This is the first time I use AWS Lambda as an API architecture.
Because im trying to implement serverless.
Let say, I have three microservices where all of the microservices hosted on AWS Lambda.
And I use AWS API Gateway as router. I also implemented Jason web token in API Gateway.
This is the public URL that the frontend will use.
URL Routing API - https://mydomain.co/v1/lambda-service1
Lambda REAL URL - https://cr7z0dds42.execute-api.ap-southeast-amazonaws.com/DEV/
URL Routing API - http://mydomain.co/v1/lambda-service2
Lambda REAL URL - https://cr7z0ddgg2.execute-api.ap-southeast-amazonaws.com/DEV/
API Routing URL - http://mydomain.co/v1/lambda-service3
Lambda REAL URL - https://cgf7z0ddgg2.execute-api.ap-southeast-amazonaws.com/DEV/
Basically, if I am currently my client / frontend, I want to call data from API number 1 by using TOKEN, i will use the API routing URL.
But there are some cases that the API number 1 needs to call service number 2 before return to client / frontend.
Currently what I do is call directly service number 2 via Lambda REAL URL, not API Routing URL from service number 1 without using TOKEN.
Is this justified?
If I got your query correctly maybe below might assist.
Justification is mainly based on the scale you expect the app you are developing and also your organisation/architecture policies (you might want to enforce).
If tokens are used for all API calls and making it consistence will make it easy when a wider team of developers working on the project down the track. Also make it easy for troubleshooting, as the scope of each Lambda function (in/outs) logic is clear and consistent.
Also another thought is around cost, API calls does cost you at scale. So that should be taken in to consideration as well during architecture. But (in my opinion) consistency in the app call flow, for the savings it might give for traffic not hitting API gateway, where the call is made directly from Lambda to internal resources might be negligible.
Anyways some thoughts to consider.
I have a few different services (generated by the Serverless Framework) that need to communicate between each other. The data is sensitive and requires authentication.
My current strategy is to create an api key for each service communicate between services using json web token like the token below.
fM61kaav8l3y_aLC/3ZZF7nlQGyYJsZVpLLiux5d84UnAoHOqLPu4dw3W7MiGwPiyN
What are some other options for communicating between services? Are there any downsides to this approach? To reiterate, the request needs to be authenticated and appropriately handle sensitive data.
Do you need sync or async communication?
A good approach would be to use events, because aws-lambda is designed as an event based system. So you could use SNS or SQS to decouple your services.
If you just want to make calls from one service to another you could invoke the lambda function directly via the aws-sdk see docs. So you would not add an API Gateways endpoint and your lambdas would stay private.
To better anwser your question you should give a short overview of your application and and an example of an interservice call you would make.
As I understand it, you intend to make the various functions in a given a service private. In doing so, each service will likely have serverless.yml file that resembles the following:
Image shows the setup for api keys used with a serverless framework rest api
While this is a suitable approach, it is less desirable than using ** Custom Authorizers**.
Custom Authorizers allow you to run an AWS Lambda Function before your targeted AWS Lambda Function. This is useful for Microservice Architectures or when you simply want to do some Authorization before running your business logic.
If you are familiar with the onEnter function when using ReactRouter, the logic among Custom Authorizers is similar.
Regarding implementation, since different services are leveraged to deploy various functions, consider deploying the function to AWS and noteing the ARN of the Lambda function. Follow these links to see the appropriate setup for the custom authorizer.
These images show the serverless.yml file for using custom authorizers when the authorizers are not part of the service but rather deployed on lambda already
The following github project aws-node-auth0-custom-authorizers-api/frontend is a good example of how to implement Custom Authorizers when the authorizer funciton is in the same service as the private function. Note your situation differs slightly yet you should expect their authorizer function logic to be simliar - only the project structure should differ