使用 post 请求调用 API 时获得 500 响应

Getting 500 response while invoking API with post request

我已经部署了集成 API 的无服务器功能。下面是代码

Serverless.yml

service: serverless-rest-api-with-dynamodb

provider:
  name: aws
  runtime: python3.8
  region: eu-west-1
  environment:
    DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
  logs:  true
functions:
  myFunc:
    handler: handler.customer
    events:
      - http:
          path: customer_details
          method: post

resources:
  Resources:
    TodosDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: CustomerTablev1
        AttributeDefinitions:

          - AttributeName: id
            AttributeType: S
          - AttributeName: CustomerName
            AttributeType: S
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
          - AttributeName: CustomerName
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

handler.py

import json


def customer(event, context):
    postData= event['body']
    return {

        'statusCode': 200,
        'body': "Hello Post accepted",
        "content-type": "application/json"
    }

下面是我为 api 添加的调用 lambda 函数的权限

{
    "Policy": "{\"Version\":\"2012-10-17\",\"Id\":\"default\",\"Statement\":
    [{\"Sid\":\"serverless-rest-api-with-dynamodb-dev-MyFuncLambdaPermissionApiGateway-dfdd22\",
    \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
    \"Action\":\"lambda:InvokeFunction\",
    \"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
    \"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##343d64543:tmx8paevk3/*/*\"}}},
    {\"Sid\":\"###23232dfecfb\",
    \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
    \"Action\":\"lambda:InvokeFunction\",
    \"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\",
    \"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:eu-west-1:##3d64543:tmx8paevk3/*/POST/customer_details\"}}},
    {\"Sid\":\"apigateway\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},
    \"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:eu-west-1:##3d64543:function:serverless-rest-api-with-dynamodb-dev-myFunc\"}]}",
    "RevisionId": "##3d64543ddf-4ecdfe"
}

我用正文请求调用了 api,例如: { “姓名”:“123” }

下面是日志

 Verifying Usage Plan for request: 33434-df-sdf##. API Key:  API Stage: tmx8paevk3/dev
API Key  authorized because method 'POST /customer_details' does not require API Key. Request will not contribute to throttle or quota limits
 Usage Plan check succeeded for API Key  and API Stage tmx8paevk3/dev
 Starting execution for request: 343-f-er-###
 HTTP Method: POST, Resource Path: /customer_details
 Method request path: 
{}
(c3434-ffg34--sd2qw) Method request query string: 
{}
 Method request headers: {Accept=application/json, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=tmx8paevk3.execute-api.eu-west-1.amazonaws.com, Accept-Encoding=gzip, deflate, X-Forwarded-Port=443, X-Amzn-Trace-Id=Root=1-5e08179b-231fd1c4058eaaa020eff0d0, Via=1.1 da86ace2d9b441802dcc77e25582499b.cloudfront.net (CloudFront), X-Amz-Cf-Id=oXgrxNvE97x-3FvOB7_85BawEcIIGe5Puzy6S9XIiKSDj8yLZQv-Ig==, X-Forwarded-For=117.204.125.144, 52.46.37.72, content-type=application/json, Accept-Language=en-US,en;q=0.8, CloudFront-Is-Desktop-Viewer=true}
 Method request body before transformations: 
{
    "name": "test"
}
Endpoint request URI: https://lambda.eu-west-1.amazonaws.com/2013-233-32/functions/arn:aws:lambda:eu-west-1:3d##:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Endpoint request headers: {x-amzn-lambda-integration-tag=##sdsd-sd23, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************d9c3f1, X-Amz-Date=20191229T030355Z, x-amzn-apigateway-api-id=tmx8paevk3, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:7###343434:tmx8paevk3/dev/POST/customer_details, Accept=application/json, User-Agent=AmazonAPIGateway_tm##we, X-Amz-Security-Token=I###12323/D######/xfP2323######//////////8B#######/334####/dsd## [TRUNCATED]
Endpoint request body after transformations: 
{
    "name": "test"
}
Sending request to https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:####:function:serverless-rest-api-with-dynamodb-dev-myFunc/invocations
Received response. Status: 200, Integration latency: 263 ms
Endpoint response headers: {Date=Sun, 29 Dec 2019 03:03:56 GMT, Content-Type=application/json, Content-Length=86, Connection=keep-alive, x-amzn-RequestId=3443D-23#, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=23d=-dere###;sampled=0}
Endpoint response body before transformations: 
{
    "statusCode": 200,
    "body": "Hello Post accepted",
    "content-type": "application/json"
}
Execution failed due to configuration error: Output mapping refers to an invalid method response: 200
Method completed with status: 500
AWS Integration Endpoint RequestId : 323d-fer-vsd###

但它仍然是 returns 500 内部错误。我搜索了不同的方法来获得解决方案,每个人都说这只是因为缺少 API 必须调用 lambda 的权限。由于我已经向 API 提供了许可,我想知道具体是什么,对此有什么解决方案? 感谢是否有人可以提供帮助?

您的回复body是这里的问题:

{
    'statusCode': 200,
    'body': "Hello Post accepted",
    "content-type": "application/json"
}

它应该是(因为您将 header 设置为 json 并传递普通文本):

{
    'statusCode': 200,
    'body': json.dumps({"reply":"Hello Post accepted"}),
    "content-type": "application/json"
}

我已经审查并测试了您的无服务器框架代码,在稍作修改后,我能够通过进行以下更改来使设置正常工作:

handler.py

    import json

    def hello(event, context):

        postData = event['body']

    # Prepare a response dictionary as required by API Gateway
        response = {
            "statusCode": 200,
            "isBase64Encoded": False,
            "headers": {},
            "content-type": "application/json",
            "body": json.dumps(postData)
        }

        return response 

Serverless.yml

service: HelloWorld
provider:
    name: aws
    runtime: python2.7
    region: eu-west-1

    iamRoleStatements:
      - Effect: Allow
        Action:
          - dynamodb:Query
          - dynamodb:Scan
          - dynamodb:GetItem
          - dynamodb:PutItem
          - dynamodb:UpdateItem
          - dynamodb:DeleteItem
        Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
    logs:  true

    environment:
        DYNAMODB_TABLE: '${self:service}-${opt:stage, self:provider.stage}'

functions:
    hello:
        handler: handler.hello
        events:
          - http:       
              path: customers-details
              method: POST
              integration: LAMBDA # Add this line

resources:
  Resources:
    TodosDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: CustomerTablev1
        AttributeDefinitions:

          - AttributeName: id
            AttributeType: S
          - AttributeName: CustomerName
            AttributeType: S
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
          - AttributeName: CustomerName
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

卷曲测试

要求:

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name":"syumaK"}' --url https://z0uu17yp6f.execute-api.eu-west-1.amazonaws.com/dev/customers-details

响应:

{"body": "{\"name\": \"syumaK\"}", "headers": {}, "content-type": "application/json", "isBase64Encoded": false, "statusCode": 200}%     

要点是,在使用 Serverless Framework 和 AWS Lambda(Lambda 代理)时,您必须添加到以下行在您的 serverless.yml 事件中:

          integration: LAMBDA

希望对您有所帮助!