Tạo hàm handle_order Lambda

Trong bước này, chúng ta sẽ tạo một hàm handle_order Lambda mới bằng cách sử dụng mẫu SAM.

Chuẩn bị

  1. Mở template.yaml trong mã nguồn bạn đã tải xuống trước đó.

    • Comment khối mã này.

      # BookApiDeployment:
      #   Type: AWS::ApiGateway::Deployment
      #   Properties:
      #     RestApiId: !Ref BookApi
      #   DependsOn:
      #     - BookApiGet
      #     - BookApiCreate
      #     - BookApiDelete
      #     - LoginApi
      #     - RegisterApi
      #     - ConfirmApi
      #     - FCAJCheckoutOrderApi
      #     - FCAJOrderManagementApi
      
      BookApiStage:
        Type: AWS::ApiGateway::Stage
        Properties:
          RestApiId: !Ref BookApi
          StageName: !Ref stage
      #     DeploymentId: !Ref BookApiDeployment
      

      Comment BookApiDeployment

  2. Chạy các lệnh dưới đây.

    sam validate
    sam build
    

    SAM validate và build

  3. Triển khai stack đã cập nhật.

    sam deploy
    

    SAM deploy

  4. Xem lại bộ thay đổi CloudFormation và xác nhận triển khai bằng cách nhập y.

    Bộ thay đổi CloudFormation và xác nhận triển khai

  5. Chờ triển khai hoàn tất.

    Triển khai hoàn tất

Tạo hàm FCAJHandleOrder

  1. Mở template.yaml trong mã nguồn bạn đã tải xuống trước đó.

    • Thêm tham số sau.

      handleOrderPathPart:
        Type: String
        Default: handle
      

      Thêm tham số handleOrderPathPart

    • Thêm các đoạn mã sau để tạo hàm FCAJHandleOrder.

      FCAJHandleOrderResource:
        Type: AWS::ApiGateway::Resource
        Properties:
          RestApiId: !Ref BookApi
          ParentId: !Ref FCAJCheckoutOrderResource
          PathPart: !Ref handleOrderPathPart
      
      FCAJHandleOrderFunction:
        Type: AWS::Serverless::Function
        Properties:
          CodeUri: fcaj-book-shop/handle_order
          Handler: handle_order.lambda_handler
          Runtime: python3.13
          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}"
      

      Thêm FCAJHandleOrderResource và Function

      FCAJHandleOrderApiOptions:
        Type: AWS::ApiGateway::Method
        Properties:
          HttpMethod: OPTIONS
          RestApiId: !Ref BookApi
          ResourceId: !Ref FCAJHandleOrderResource
          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
      

      Thêm FCAJHandleOrderApiOptions

      FCAJHandleOrderApi:
        Type: AWS::ApiGateway::Method
        Properties:
          HttpMethod: POST
          RestApiId: !Ref BookApi
          ResourceId: !Ref FCAJHandleOrderResource
          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/${FCAJHandleOrderFunction.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
      
      FCAJHandleOrderApiInvokePermission:
        Type: AWS::Lambda::Permission
        Properties:
          FunctionName: !Ref FCAJHandleOrderFunction
          Action: lambda:InvokeFunction
          Principal: apigateway.amazonaws.com
          SourceAccount: !Ref "AWS::AccountId"
      

      Thêm FCAJHandleOrderApi và InvokePermission

  2. Cấu trúc thư mục như sau.

    fcaj-book-shop
    ├── fcaj-book-shop
    │   ├── checkout_order
    │   │   └── checkout_order.py
    │   ├── order_management
    │   │   └── order_management.py
    │   ├── handle_order
    │   │   └── handle_order.py
    │   ├── ...
    │
    └── template.yaml
    
    • Tạo thư mục handle_order trong thư mục fcaj-book-shop/fcaj-book-shop/.

    • Tạo tệp handle_order.py và sao chép mã sau vào đó.

      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 from 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('Successfully handled order')
          }
      

      handle_order.py

  3. Bỏ comment khối mã này.

    BookApiDeployment:
      Type: AWS::ApiGateway::Deployment
      Properties:
        RestApiId: !Ref BookApi
      DependsOn:
        - BookApiGet
        - BookApiCreate
        - BookApiDelete
        - LoginApi
        - RegisterApi
        - ConfirmApi
        - FCAJCheckoutOrderApi
        - FCAJOrderManagementApi
        - FCAJHandleOrderApi
    
    BookApiStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        RestApiId: !Ref BookApi
        StageName: !Ref stage
        DeploymentId: !Ref BookApiDeployment
    

    Bỏ comment BookApiDeployment

  4. Chạy các lệnh dưới đây.

    sam validate
    sam build
    

    SAM validate và build

  5. Triển khai stack đã cập nhật.

    sam deploy
    

    SAM deploy với FCAJHandleOrder

  6. Chờ triển khai hoàn tất.

    Triển khai hoàn tất

Kiểm tra việc tạo

  1. Mở Amazon API Gateway console.

    • Nhấp vào fcaj-serverless-api. Danh sách API Gateway
    • Nhấp vào Resources trên menu bên trái.
    • Kiểm tra /handle vừa tạo bên dưới /order. API Gateway Resources
  2. Mở Amazon Lambda console.

    • Nhấp vào Functions trên menu bên trái.
    • Chọn hàm handle_order. Danh sách Lambda Functions
    • Tại trang handle_order, kiểm tra hàm vừa được tạo. Chi tiết hàm handle_order