This is a series of articles about setting up a complex Serverless backend infrastructure with AWS SAM and CloudFormation.
Here is the index of all the articles in case you want to jump to any of them:
1. Setup of AppSync and API Gateway with Multiple AWS Cognito User Pools
2. Configuring S3 Buckets with Permissions and Access Roles in AWS Cognito AuthRole
3. Intro to DynamoDB Resolvers for AppSync Implementation
4. Intro to Lambda Resolvers for AppSync Implementation
5. Configuring an AWS VPC to Include Lambda Resolvers with a Fixed IP
6. Intro to Pipeline Resolvers for AppSync Implementation
7. Handling Lambda Resolver Timeouts with SNS Messages
Introduction
While DynamoDB resolvers offer direct mappings in AppSync, sometimes more complex logic is required. This is where AWS Lambda comes in. In this guide, we'll delve into using Lambda resolvers in AppSync for CRUD operations.
Why Lambda Resolvers?
Lambda resolvers provide flexibility. They allow developers to run custom logic, integrate with multiple data sources, or even call external APIs before returning data to AppSync.
The Code
Setting Up Lambda Resolvers for CRUD Operations
1. Create: Set up a Lambda function to handle data creation. The function can validate input, integrate with other services, and then store data in DynamoDB or another data source.
2. Read: Implement a Lambda function to fetch data. This function can aggregate data from multiple sources or perform complex filtering before returning results.
3. Update: Design a Lambda function to handle data updates. This function can run business logic, validate data changes, and then update the data source.
4. Delete: Create a Lambda function to manage data deletion. Before removing data, the function can archive data, notify other services, or perform cleanup operations.
To avoid too many similar examples, here is how a Lambda function is configured as a data source and how it is attached to AppSync.
Resources:
# Lambda Function
MyLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Handler: "index.handler"
Role: !GetAtt LambdaExecutionRole.Arn
FunctionName: "MyAppSyncLambdaDataSource"
Code:
S3Bucket: "myBucket"
S3Key: "code/myLambda.zip"
Runtime: "nodejs14.x"
MemorySize: 256
Timeout: 10
# IAM Role for Lambda Execution
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "LambdaExecutionPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
# AppSync Lambda DataSource
AppSyncLambdaDataSource:
Type: "AWS::AppSync::DataSource"
Properties:
ApiId: !GetAtt AppSyncAPI.ApiId
Name: "LambdaDataSource"
Type: "AWS_LAMBDA"
LambdaConfig:
LambdaFunctionArn: !GetAtt MyLambdaFunction.Arn
ServiceRoleArn: !GetAtt AppSyncLambdaRole.Arn
# IAM Role for AppSync to call Lambda
AppSyncLambdaRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "appsync.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "AppSyncLambdaPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: !GetAtt MyLambdaFunction.Arn
Conclusion
Lambda resolvers in AppSync offer unparalleled flexibility. By allowing custom logic and integrations, they enable developers to build robust and dynamic GraphQL APIs.
Please note that the code examples have been simplified to help understand the approach and the resources. Some adjustments might be needed.
---------
Next UP: Part 5. Configuring an AWS VPC to Include Lambda Resolvers with a Fixed IP