In this step, we will create a new handle_order Lambda function using a SAM template.
Open template.yaml in the source code you downloaded before.
Comment this code block.
# BookApiDeployment:
# Type: AWS::ApiGateway::Deployment
# Properties:
# RestApiId: !Ref BookApi
# DependsOn:
# - BookApiGet
# - BookApiCreate
# - BookApiDelete
# - LoginApi
# - RegisterApi
# - ConfirmApi
# - FcjCheckoutOrderApi
# - FcjOrderManagementApi
BookApiStage:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref BookApi
StageName: !Ref stage
# DeploymentId: !Ref BookApiDeployment
Run the below commands.
sam build
sam validate
sam deploy
Open template.yaml in the source code you downloaded before.
Add the following scripts below to create FcjHandleOrder function.
handleOrderPathPart:
Type: String
Default: handle
FcjHandleOrderResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref BookApi
ParentId: !Ref FcjCheckoutOrderResource
PathPart: !Ref handleOrderPathPart
FcjHandleOrderFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcj-book-shop/handle_order
Handler: handle_order.lambda_handler
Runtime: python3.11
FunctionName: handle_order
Environment:
Variables:
ORDER_TABLE_NAME: !Ref orderTable
SQS_QUEUE_URL: !Ref checkoutQueueUrl
Architectures:
- x86_64
Policies:
- Statement:
- Sid: VisualEditor0
Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:BatchWriteItem
Resource:
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${orderTable}"
- Sid: VisualEditor1
Effect: Allow
Action:
- sqs:*
Resource:
- !Sub "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:${checkoutQueueName}"
FcjHandleOrderApiOptions:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: OPTIONS
RestApiId: !Ref BookApi
ResourceId: !Ref FcjHandleOrderResource
AuthorizationType: NONE
Integration:
Type: MOCK
IntegrationResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: "'*'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,GET,DELETE'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
FcjHandleOrderApi:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: POST
RestApiId: !Ref BookApi
ResourceId: !Ref FcjHandleOrderResource
AuthorizationType: NONE
Integration:
Type: AWS_PROXY
IntegrationHttpMethod: POST # For Lambda integrations, you must set the integration method to POST
Uri: !Sub >-
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${FcjHandleOrderFunction.Arn}/invocations
MethodResponses:
- StatusCode: "200"
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
method.response.header.Access-Control-Allow-Methods: true
method.response.header.Access-Control-Allow-Headers: true
FcjHandleOrderApiInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref FcjHandleOrderFunction
Action: lambda:InvokeFunction
Principal: apigateway.amazonaws.com
SourceAccount: !Ref "AWS::AccountId"
The directory structure is as follows.
fcj-book-shop-sam-ws3
├── fcj-book-shop
│ ├── checkout_order
│ │ └── checkout_order.py
│ ├── order_management
│ │ └── order_management.py
│ ├── handle_order
│ │ └── handle_order.py
│ ├── ...
│
└── template.yaml
Create handle_order folder in fcj-book-shop-sam-ws6/fcj-book-shop/ folder.
Create handle_order.py file and copy the following code to it.
import json
import boto3
import os
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token"
}
dynamodb = boto3.resource('dynamodb')
sqs = boto3.client('sqs')
# Define the DynamoDB table name and SQS queue URL
table_name = os.getenv('ORDER_TABLE_NAME')
queue_url = os.getenv('SQS_QUEUE_URL')
def lambda_handler(event, context):
# Get product body info from the event
products = json.loads(event['body'])
books = products['books']
receipt_handle = products['receiptHandle']
# Write product info to DynamoDB
table = dynamodb.Table(table_name)
try:
for book in books:
data = {
'id': products['id'],
'book_id': book['id'],
'name': book['name'],
'qty': book['qty'],
'price': str(products['price'])
}
table.put_item(Item=data)
except Exception as e:
print(f"Error writing to DynamoDB: {e}")
raise Exception(f"Error writing to DynamoDB: {e}")
# Delete message in SQS
try:
sqs.delete_message(
QueueUrl=queue_url,
ReceiptHandle=receipt_handle
)
except Exception as e:
print(f"Error deleting message from SQS: {e}")
raise Exception(f"Error deleting message from SQS: {e}")
return {
'statusCode': 200,
'headers': headers,
'body': json.dumps('Order processed successfully')
}
Uncomment this code block.
BookApiDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref BookApi
DependsOn:
- BookApiGet
- BookApiCreate
- BookApiDelete
- LoginApi
- RegisterApi
- ConfirmApi
- FcjCheckoutOrderApi
- FcjOrderManagementApi
- FcjHandleOrderApi
BookApiStage:
Type: AWS::ApiGateway::Stage
Properties:
RestApiId: !Ref BookApi
StageName: !Ref stage
DeploymentId: !Ref BookApiDeployment
Run the below commands.
sam build
sam validate
sam deploy
Open Amazon API Gateway console.
Open Amazon Lambda console.