By using AWS re:Post, you agree to the Terms of Use

Why does Lambda URL convert the request body from JSON to string?

0

Hi there,

We are making use of the new Lambda URL feature. When we invoke the URL of our function to send a POST request with a simple body, what we see in the event that the function receives is that the body is shown as a string, and not as a JSON.

For a simple request body that looks like:

{
    "accountId": "123456789012",
    "duration": 5
}

this is what we see in the event object that is passed to the function upon invocation:

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/",
    "rawQueryString": "",
    "headers": {
        "content-length": "55",
        "x-amz-date": "20220509T192924Z",
        "x-forwarded-proto": "https",
        "x-forwarded-port": "443",
        "x-forwarded-for": "OBFUSCATED",
        "x-amz-security-token": "OBFUSCATED",
        "accept": "*/*",
        "x-amzn-trace-id": "OBFUSCATED",
        "host": "OBFUSCATED",
        "content-type": "application/json",
        "accept-encoding": "gzip, deflate, br",
        "user-agent": "Thunder Client (https://www.thunderclient.com)"
    },
    "requestContext": {
        "accountId": "123456789012",
        "apiId": "OBFUSCATED",
        "authorizer": {
            "iam": {
                "accessKey": "OBFUSCATED",
                "accountId": "123456789012",
                "callerId": "OBFUSCATED",
                "cognitoIdentity": "None",
                "principalOrgId": "OBFUSCATED",
                "userArn": "arn:aws:sts::123456789012:assumed-role/ExampleRole",
                "userId": "OBFUSCATED"
            }
        },
        "domainName": "OBFUSCATED",
        "domainPrefix": "OBFUSCATED",
        "http": {
            "method": "POST",
            "path": "/",
            "protocol": "HTTP/1.1",
            "sourceIp": "OBFUSCATED",
            "userAgent": "Thunder Client (https://www.thunderclient.com)"
        },
        "requestId": "b76a957b-2f63-4fd8-8944-65hy79b62711",
        "routeKey": "$default",
        "stage": "$default",
        "time": "09/May/2022:19:29:28 +0000",
        "timeEpoch": 1652124568118
    },
    "body": "{\\n    \"accountId\": \"123456789012\",\\n    \"duration\": 5\\n}",
    "isBase64Encoded": "False"
}

As you can see the value of the body node is wrapped in " and AWS has added also the new line characters together with escape characters.

Because of this, we can't simply parse the body, and therefore we always have to deserialize it and remove the newline characters.

Any idea why this happens? Am I missing something when I send the request?

Thank you in advance!

asked a month ago78 views
2 Answers
0
Accepted Answer

Hey Pier, you are right. My answer was wrong in your context, sorry about that. But the body being string is by design as noted by Uri.

answered a month ago
0

This is by design.

I think you are only able to change it using API Gateway. Lambda functions with PROXY integration accelerates your integration process as you don't need to create the request and response templates. And, as the Lambda can receive binary payload in BASE64, the body should have a type for this case also, as, the payload is not JSON.

You can still receive the payload as JSON if you setup the request and response templates by yourself.

answered a month ago
  • Thank you for your answer, Eduardo.

    How can set up a request template for a Lambda URL? I haven't seen that being supported for Lambda URLs. The link you posted is for API Gateway.

  • The reason provided by Eduardo is correct, although the details relate to API Gateway with Lambda and not Lambda Function URLs.

    I think that depending on the programming language, you should be able to parse it easily, e.g., in Python use something like body = json.loads(event.body)

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions