Serverless graphql split into micro services - amazon-web-services

How can i split my serverless graphql endpoint which runs in one lambda function into multiple micro lambda functions for scalability?
is it need to have multiple graphql end points ? or need to have only one graphql endpoint and resolvers split into seperate lambda functions ? what is the best architecture ?

Usually, you access the entire GraphQL API with a single endpoint.
From GraphQL.org:
GraphQL APIs are organized in terms of types and fields, not endpoints. Access the full capabilities of your data from a single endpoint. [emphasis added]
Of course, you could have multiple GraphQL APIs but those would be like separate services and your clients would need which one to access for which data.
You can have a single GraphQL endpoint and then dispatch some work to multiple Lambda functions but it doesn't necessarily need to be more scalable than a single function. Keep in mind that this single function will be run possible multiple times so having one function that does two things is not less scalable than two functions that do one thing each.
For example How to write GraphQL Apps using AWS Lambda
on Cloud Academy recommends using a single AWS Lambda function for the entire API, using Express.
Maybe some other ways to build your service may be better suited to your needs, e.g. see Designing a GraphQL API on AWS AppSync Developer Guide.

Related

AWS HTTP API Gateway as a proxy to private S3 bucket

I have a private S3 bucket with lots of small files. I'd like to expose the contents of the bucket (only read-only access) using AWS API Gateway as a proxy. Both S3 bucket and AWS API Gateway belong to the same AWS account and are in the same VPC and Availability Zone.
AWS API Gateway comes in two types: HTTP API, REST API. The configuration options of REST API are more advanced, additionally, REST API supports much more AWS services integrations than the HTTP API. In fact, the use case I described above is fully covered in one of the documentation tabs of REST API. However, REST API has one huge disadvantage - it's about 70% more expensive than the HTTP API, the price comes with more configuration options but as for now, I need only one - integration with the S3 service that's why I believe this type of service is not well suited for my use case. I started searching if HTTP API can be integrated with S3, and so far I haven't found any way to achieve it.
I tried creating/editing service-linked roles associated with the HTTP API Gateway instance, but those roles can't be edited (only read-only access). As for now, I don't have any idea where I should search next, or if my goal is even achievable using HTTP API.
I am a fan of AWSs HTTP APIs.
I work daily with an API that serves a very similar purpose. The way I have done it is by using AWS Lambda functions integrated with the APIs paths.
What works for me is this:
Define your API paths, and integrate them with AWS Lambda functions.
Have your integrated Lambda function return a signed URL for any objects you want to provide access to through API calls.
There are several different ways to pass the name of the object(s) you want to the Lambda function servicing the API call.
This is the short answer. I plan to give a longer answer at a later time. But this has worked for me.

Use graphQL with API Gateway (apollo-server-lambda) vs. AppSync

This is a question keeps confusing me. Although AppSync is marketed as for GraphQL while API Gateway is for REST. But API Gateway could also work with GraphQL via apollo server in lambda.
So what actually makes one a better option over the other?
It depends on how much control you want over your backend service execution, how much code you feel like writing, and then of course how much you want to pay.
With API Gateway and Lambda you are writing a handler function that executes a full graphql request against your resolver definitions that you write in whatever language your Lambda runtime is set to. You have to consider how much memory your application will need, and what kind of features you want to support. You will also need to do some legwork to get subscriptions working with websockets.
AWS AppSync is more of a managed service, where you register your GraphQL schema with AppSync and the service takes care of things like query validation, batching calls, and of course out-of-the-box subscriptions. In it you only need to define how you want to "map" the GraphQL request using VTL (Velocity Templating Language) to define calls to your downstream data sources ie. specifically DynamoDB, ElasicSearch, HTTP, Aurora Serverless RDS, or Lambda. Keep in mind, the Lambda functions you write for AppSync only have to handle a single resolver, whereas with Apollo Server you are writing all of the resolver logic in your code.
Ultimately whichever way you choose has its pros and cons. With Apollo Server on Lambda you get to control the full HTTP GraphQL request cycle at the expense of additional complexity to do so. With AppSync you have a more "managed" service where you only need to define the resolvers to talk to your data sources (and in many cases, these can be auto-generated for you using Amplify CLI) at the expense of having finer control over the whole GraphQL request.

Calling lambda from another lambda or exposing api through api-gateway

I am contemplating if I should invoke lambda directly from another lambda or should I expose api through api-gateway in front of lambda. I am looking for pros and cons for both.
Approach #1 Using API Gateway
API Gateway and Lambda have one of the best integrations for serverless applications. It is very widely used and offers a ton of features - proxy integration, mapping templates, custom domain names and different types of authentication.
However, with these pros comes the cons due to some limits with using API Gateway. API Gateway has a default integration time out (a hard limit) of 29 seconds - which means the Lambda function needs to send back a response to API within this time frame or API fails with a 504 response. You may review other limits related to API Gateway here.
Approach #2 Lambda invoking Lambda
I'm not a big fan of this approach and have multiple reasons for it. I'll start with the additional code you have to write - same task with better features can be done by API Gateway with simple configurations on the AWS console.
A container calling another container(Lambda) can result it container-related problems - networking, container reuse and even managing IAM permissions properly.
Also, a Lambda function can be invoked by only three options - SDK, CLI or an entity that has "Invoke" permission. So basically, you need to have some kind of resource in front of your first Lambda to invoke it which will then invoke the second. In my opinion, API Gateway is the best front-end you can have for Lambda which is exactly AWS had in mind building these two services.
One of the pros I can think of this approach is the time out value - Lambda can run for up to max of 15 mins. Unless your client does not require a response back pretty quickly, you can run these two Lambda functions for a longer time to execute code.
Summary
All the above information was pretty general for anyone looking to use API Gateway and Lambda. I'll say it again that using API Gateway is a more convenient and useful approach however it may depend on your use-case. Hope this helps!

Generate one API Gateway for multiple lambdas - in automated way

I would like to build API Gateway in automated way (using some kind of framework), but I cannot find ideal solution.
The problem is that every framework is using one lambda (proxy) for entire API Gateway. I'm intrested in one API and multiple lambdas (with different persmissions and node_modules).
I was trying:
- claudiajs
- severless
- dawson
Do we have other options or I need to create it by myself via CloudFormation?
Thanks in advance!
So all Lambda's on AWS have their own execution roles, regardless of framework. Under serverless (serverless docs) you can specify a role for each Lambda by following the example in that link.
You can also individually package functions see this forum thread for more info.

Serverless - Options for communicating between services?

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