Tạo POST API

Trong bước này, chúng ta sẽ thêm phương thức POST vào REST API để frontend có thể tạo sách mới thông qua hàm Lambda book_create.

Việc thêm một method mới yêu cầu tạo lại API deployment. Vì BookApiDeployment không thể được cập nhật trực tiếp trong khi một stage đang phụ thuộc vào nó, chúng ta phải thực hiện theo hai giai đoạn:

  • Giai đoạn 1: Comment out deployment, deploy để tách stage khỏi nó, cho phép CloudFormation xóa deployment cũ.
  • Giai đoạn 2: Thêm POST method, bỏ comment deployment (giờ với cả GET + POST là dependencies), và deploy lại.

Giai đoạn 1 — Xóa Deployment cũ

  1. Mở tệp template.yaml trong thư mục fcaj-book-shop.

  2. Comment out khối BookApiDeployment, và comment cả dòng DeploymentId trong BookApiStage, để CloudFormation có thể xóa deployment cũ một cách sạch sẽ:

    # BookApiDeployment:
    #   Type: AWS::ApiGateway::Deployment
    #   Properties:
    #     RestApiId: !Ref BookApi
    #   DependsOn:
    #     - BookApiGet
    
    BookApiStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        RestApiId: !Ref BookApi
        StageName: !Ref stage
        # DeploymentId: !Ref BookApiDeployment
    

    Comment BookApiDeployment

  3. Chạy các lệnh sau để validate, build và deploy:

    sam validate
    sam build
    

    SAM Validate & Build - Giai đoạn 1

    sam deploy
    

    Changeset hiển thị:

    • Modify BookApiStage (AWS::ApiGateway::Stage)
    • Delete BookApiDeployment (AWS::ApiGateway::Deployment)

    Nhập y để xác nhận.

    SAM Deploy - Changeset Giai đoạn 1

  4. Chờ quá trình triển khai hoàn tất.

    Deploy hoàn tất - Giai đoạn 1

Tại sao cần hai giai đoạn deploy?: BookApiDeployment của API Gateway là một snapshot của tất cả các method được đăng ký tại thời điểm tạo. Bạn không thể chỉ thêm method mới và cập nhật deployment hiện có — bạn cần tạo một deployment mới hoàn toàn để capture method mới. CloudFormation xử lý điều này bằng cách xóa deployment cũ trước (Giai đoạn 1), sau đó tạo mới bao gồm cả GET lẫn POST (Giai đoạn 2).

Giai đoạn 2 — Thêm POST Method và Deploy lại

  1. Thêm method BookApiCreate và permission BookApiCreateInvokePermission sau BookApiGetInvokePermission:

    BookApiCreate:
      Type: AWS::ApiGateway::Method
      Properties:
        HttpMethod: POST
        RestApiId: !Ref BookApi
        ResourceId: !Ref BookApiResource
        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/${BookCreate.Arn}/invocations
          IntegrationResponses:
            - StatusCode: "200"
              ResponseParameters:
                method.response.header.Access-Control-Allow-Origin: "'*'"
                method.response.header.Access-Control-Allow-Methods: "'GET,POST,OPTIONS'"
                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: "'*'"
              method.response.header.Access-Control-Allow-Methods: "'GET,POST,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
    
    BookApiCreateInvokePermission:
      Type: AWS::Lambda::Permission
      Properties:
        FunctionName: !Ref BookCreate
        Action: lambda:InvokeFunction
        Principal: apigateway.amazonaws.com
        SourceAccount: !Ref "AWS::AccountId"
    

    BookApiCreate và BookApiCreateInvokePermission

  2. Bây giờ bỏ comment khối BookApiDeployment và dòng DeploymentId trong BookApiStage. Cập nhật DependsOn để bao gồm cả BookApiGet lẫn BookApiCreate:

    BookApiDeployment:
      Type: AWS::ApiGateway::Deployment
      Properties:
        RestApiId: !Ref BookApi
      DependsOn:
        - BookApiGet
        - BookApiCreate
    
    BookApiStage:
      Type: AWS::ApiGateway::Stage
      Properties:
        RestApiId: !Ref BookApi
        StageName: !Ref stage
        DeploymentId: !Ref BookApiDeployment
    

    Bỏ comment BookApiDeployment với DependsOn cả hai

  3. Chạy lại các lệnh để build và deploy:

    sam validate
    sam build
    

    SAM Validate & Build - Giai đoạn 2

    sam deploy
    

    Changeset hiển thị các tài nguyên mới:

    • Add BookApiCreate (AWS::ApiGateway::Method)
    • Add BookApiDeployment (AWS::ApiGateway::Deployment)
    • Add BookApiCreateInvokePermission (AWS::Lambda::Permission)
    • Modify BookApiStage (AWS::ApiGateway::Stage)

    Nhập y để xác nhận.

    SAM Deploy - Changeset Giai đoạn 2

  4. Chờ quá trình triển khai hoàn tất. Bạn sẽ thấy Successfully created/updated stack - fcaj-book-shop in ap-southeast-1.

    Deploy hoàn tất - Giai đoạn 2

Kiểm tra trên AWS Console

  1. Mở AWS API Gateway console. Nhấp vào fcaj-serverless-api REST API.

    API Gateway - fcaj-serverless-api

  2. Tại trang fcaj-serverless-api:

    • Nhấp vào Resources trong menu bên trái.
    • Chọn POST trong resource /books.
    • Nhấp vào tooltip Lambda integration — xác nhận hàm được tích hợp là book_create.

    Resources - POST /books - Lambda integration book_create

  3. Nhấp vào Stages trong menu bên trái.

    • Mở rộng staging/books → chọn POST.
    • Sao chép và lưu lại Invoke URL — đây là URL cơ sở giống với GET endpoint, vì cả hai method đều chia sẻ cùng đường dẫn resource /books.

    Ví dụ: https://1bupjnr42d.execute-api.ap-southeast-1.amazonaws.com/staging/books

    Stages - staging/POST - Invoke URL

Invoke URL của GETPOST là giống nhau — cả hai đều trỏ đến …/staging/books. HTTP method (GET hay POST) trong request sẽ quyết định hàm Lambda nào được kích hoạt: GET gọi books_list, còn POST gọi book_create.