An open API service indexing awesome lists of open source software.

https://github.com/devhabeeblateef/serverless-react-app-with-aws

A simple serverless application that allows users to add items to a list using AWS services. The app uses S3, API Gateway, Lambda, and DynamoDB to provide seamless scalability and functionality.
https://github.com/devhabeeblateef/serverless-react-app-with-aws

aws aws-lambda react serverless

Last synced: 9 months ago
JSON representation

A simple serverless application that allows users to add items to a list using AWS services. The app uses S3, API Gateway, Lambda, and DynamoDB to provide seamless scalability and functionality.

Awesome Lists containing this project

README

          

```markdown
Serverless Item Add Application

This is a serverless application that allows users to manage a list of items, including adding, retrieving, updating, and deleting items. The architecture leverages AWS services such as DynamoDB, API Gateway, Lambda, and CloudFormation to provide a scalable and cost-efficient solution.

Architecture Overview

The application follows a serverless design, with the following components:

DynamoDB: Acts as the database to store item details.
Lambda Function: Handles business logic and integrates with DynamoDB.
API Gateway: Provides a RESTful API interface for the frontend to interact with the backend.
CloudFormation: Automates the deployment of infrastructure resources.

Setup and Deployment

I used the AWS Management Console to create and deploy the following resources:

1. DynamoDB Table
Created a table named `all-items` with the following attributes:
Primary Key: `itemId` (String).
Provisioned throughput set to 1 read/write unit (for demonstration purposes).

2. Lambda Function
A Node.js function was created to process API requests.
The function supports the following operations:
GET: Retrieve items or a single item by ID.
PUT: Add or update items in the database.
DELETE: Remove an item from the database.
- The Lambda function was given permissions to access DynamoDB and log to CloudWatch.

3. API Gateway
Configured an HTTP API to expose endpoints for interacting with the Lambda function.
API Methods:
GET /items: Retrieve all items.
GET /items/{id}: Retrieve a specific item by ID.
PUT /items: Add or update an item.
DELETE /items/{id}: Delete an item by ID.
Enabled CORS for cross-origin requests.

4. CloudFormation Template

To streamline and automate resource creation, I created the following CloudFormation template:

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Serverless Item Add Application

Resources:
# DynamoDB Table
ItemDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: 'itemId'
AttributeType: 'S'
KeySchema:
- AttributeName: 'itemId'
KeyType: 'HASH'
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: all-items

# Lambda Function
ItemLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: nodejs18.x
Role: !GetAtt ItemFunctionExecutionRole.Arn
Handler: index.handler
Code:
ZipFile: |
const AWS = require("aws-sdk");
const dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
let body, statusCode = 200;
try {
switch (event.routeKey) {
case "GET /items":
body = await dynamo.scan({ TableName: "all-items" }).promise();
break;
case "GET /items/{id}":
body = await dynamo.get({
TableName: "all-items",
Key: { itemId: event.pathParameters.id }
}).promise();
break;
case "PUT /items":
let requestJSON = JSON.parse(event.body);
await dynamo.put({
TableName: "all-items",
Item: requestJSON
}).promise();
body = `Added item ${requestJSON.itemId}`;
break;
case "DELETE /items/{id}":
await dynamo.delete({
TableName: "all-items",
Key: { itemId: event.pathParameters.id }
}).promise();
body = `Deleted item ${event.pathParameters.id}`;
break;
default:
throw new Error(`Unsupported route: "${event.routeKey}"`);
}
} catch (err) {
statusCode = 400;
body = err.message;
}
return { statusCode, body: JSON.stringify(body) };
};

# API Gateway
ItemAPI:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: items-api
ProtocolType: HTTP
Target: !GetAtt ItemLambdaFunction.Arn

# Lambda Permissions for API Gateway
APIInvokeLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref ItemLambdaFunction
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ItemAPI}/$default

# Lambda Execution Role
ItemFunctionExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: LambdaDynamoDBAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
- dynamodb:DeleteItem
- dynamodb:Scan
Resource: !GetAtt ItemDynamoDBTable.Arn

Outputs:
InvokeURL:
Value: !Sub https://${ItemAPI}.execute-api.${AWS::Region}.amazonaws.com
Description: The URL to invoke the API.
```

### Deployment Steps:
1. Navigated to the **CloudFormation Console** in the AWS Management Console.
2. Uploaded the above YAML template.
3. Launched the stack and verified all resources were created successfully.
4. Retrieved the API Gateway invoke URL from the **Outputs** section of the CloudFormation stack.

## **Testing**
1. Used **Postman** or a browser to test the API endpoints:
- `PUT /items` with a JSON payload to add an item.
- `GET /items` to fetch all items.
- `GET /items/{id}` to retrieve a specific item.
- `DELETE /items/{id}` to delete an item.
2. Verified that DynamoDB stored and updated the data as expected.

## **Key Features**
- Fully serverless and scalable architecture.
- Automated deployment with CloudFormation.
- Seamless integration of API Gateway, Lambda, and DynamoDB.

## **Next Steps**
- Add authentication using Amazon Cognito or IAM roles.
- Optimize DynamoDB with indexes for more complex queries.
- Implement monitoring using AWS CloudWatch Metrics and Logs.
```