API Gateway POST method working during tests, but not with postman

前端 未结 3 1044
生来不讨喜
生来不讨喜 2021-02-10 02:35

i will try to explain my problem clearly.

I have an API who writes something in DynamoDB with a lambda function written in Node.js. When i\'m calling it within the AWS c

3条回答
  •  日久生厌
    2021-02-10 02:58

    That's because when testing from AWS Lambda's console, you're sending the JSON you actually expect. But when this is invoked from API Gateway, the event looks different.

    You'll have to access the event.body object in order to get your JSON, however, the body is a Stringified JSON, meaning you'll have to first parse it.

    You didn't specify what language you're coding in, but if you're using NodeJS you can parse the body like this:

    JSON.parse(event.body).

    If you're using Python, then you can do this:

    json.loads(event["body"])

    If you're using any other language, I suggest you look up how to parse a JSON from a given String

    That gives what you need.

    This is what an event from API Gateway looks like:

    {
        "path": "/test/hello",
        "headers": {
          "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
          "Accept-Encoding": "gzip, deflate, lzma, sdch, br",
          "Accept-Language": "en-US,en;q=0.8",
          "CloudFront-Forwarded-Proto": "https",
          "CloudFront-Is-Desktop-Viewer": "true",
          "CloudFront-Is-Mobile-Viewer": "false",
          "CloudFront-Is-SmartTV-Viewer": "false",
          "CloudFront-Is-Tablet-Viewer": "false",
          "CloudFront-Viewer-Country": "US",
          "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com",
          "Upgrade-Insecure-Requests": "1",
          "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
          "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)",
          "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==",
          "X-Forwarded-For": "192.168.100.1, 192.168.1.1",
          "X-Forwarded-Port": "443",
          "X-Forwarded-Proto": "https"
        },
        "pathParameters": {
          "proxy": "hello"
        },
        "requestContext": {
          "accountId": "123456789012",
          "resourceId": "us4z18",
          "stage": "test",
          "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9",
          "identity": {
            "cognitoIdentityPoolId": "",
            "accountId": "",
            "cognitoIdentityId": "",
            "caller": "",
            "apiKey": "",
            "sourceIp": "192.168.100.1",
            "cognitoAuthenticationType": "",
            "cognitoAuthenticationProvider": "",
            "userArn": "",
            "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48",
            "user": ""
          },
          "resourcePath": "/{proxy+}",
          "httpMethod": "GET",
          "apiId": "wt6mne2s9k"
        },
        "resource": "/{proxy+}",
        "httpMethod": "GET",
        "queryStringParameters": {
          "name": "me"
        },
        "stageVariables": {
          "stageVarName": "stageVarValue"
        },
        "body": "'{\"user-id\":\"123\",\"name\":\"name\", \"firstname\":\"firstname\"}'"
      }
    

    EDIT

    After further discussion in the comments, one more problem is that the you're using the DynamoDB API rather than the DocumentClient API. When using the DynamoDB API, you must specify the types of your objects. DocumentClient, on the other hands, abstracts this complexity away.

    I have also refactored your code a little bit (only dealing with POST at the moment for the sake of simplicity), so you can make use of async/await

    'use strict';
    
    console.log('Function Prep');
    const AWS = require('aws-sdk');
    const dynamo = new AWS.DynamoDB.DocumentClient();
    
    exports.handler = async (event) => {
    
        switch (event.httpMethod) {
            case 'POST':
                await dynamo.put({TableName: 'users', Item: JSON.parse(event.body)}).promise();
                break;
            default:
                throw new Error(`Unsupported method "${event.httpMethod}"`);
        }
        return {
            statusCode: 200,
            body: JSON.stringify({message: 'Success'})
        }
    };
    

    Here's the Item in DynamoDB:

    And this is my Postman request:

    With proper headers:

    When creating API Gateway, I checked the box Use Lambda Proxy integration. My API looks like this:

    If you reproduce these steps it should just work.

提交回复
热议问题