Serverless-offline: Need to double parse request.body

Created on 14 Dec 2016  ·  21Comments  ·  Source: dherault/serverless-offline

Hi, probably it's related to #172 but I will still describe my problem. In a function's handler on AWS I can just parse request.body using the following line of code:

const body = JSON.parse(request.body);

However, locally using serverless-offline I have to do:

let body = JSON.parse(request.body);
if (_.isString(body)) {
  body = JSON.parse(body);
}

It seems like it's stringified two times. I think serverless-offline shouldn't stringify request body as it's a job for request creator. Request body should always be a string.

Here is also a difference between how body looks like on AWS and locally:

// AWS
'"{"email":"[email protected]","password":"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"}"'
// locally
'"{\"email\":\"[email protected]\",\"password\":\"5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8\"}"'
bug help wanted

Most helpful comment

Yes, this works again with 3.11.0. Thanks 👍

My only worry is that, to my understanding, the PR #214 rolls back PR #212 and thus the original issue reported by @jagi, @imackinn and @em0ney (and others) might either still exist or happen again in 3.11.0. I never ran into the original issue in first place as I'm using Lambda Proxy.

All 21 comments

Hi @jagi thanks for reporting this.
Anyone wanna PR this?

@jagi does this issue still appear in v3.8.3?

@ansraliant I will check it on Monday and let you know

@ansraliant yes bug still appears in v3.8.3. I still need to double parse request.body.

I'm seeing an even crazier manifestation of this issue. Chrome says it's sending:

{"firstName":"Test","lastName":"Data","email":"[email protected]","title":"Test Title","group":"General","role":"Standard User","enabled":true}

When I print out the JSON.stringify(event), AWS Lambda prints out a ton of text that contains:

"body": "{\"firstName\":\"Test\",\"lastName\":\"Data\",\"email\":\"[email protected]\",\"title\":\"Test Title\",\"group\":\"General\",\"role\":\"Standard User\",\"enabled\":true}"

That looks right to me. But in serverless-offline mode I see the following:

"body":"{\"{\\\"firstName\\\":\\\"Test\\\",\\\"lastName\\\":\\\"Data\\\",\\\"email\\\":\\\"[email protected]\\\",\\\"title\\\":\\\"Test Title\\\",\\\"group\\\":\\\"General\\\",\\\"role\\\":\\\"Standard User\\\",\\\"enabled\\\":true}\":\"\"}"

Note how the real body is now a key with an empty string value.

My workaround for this is:

// We do this to work around: https://github.com/dherault/serverless-offline/issues/173
module.exports.getBodyAsObject = function(event) {
  let body = JSON.parse(event.body);
  if (Object.keys(body).length == 1) {
    let firstKey = Object.keys(body)[0];
    if(body[firstKey] === "") {
      body = JSON.parse(firstKey);
    }
  }
  return body;
};

@rsshilli I think that it's actually the same as in my case. Have you tried my workaround?

Hi @rsshilli can you please give me your setup. I'm (finally) tackling this issue but I cannot reproduce it. Can you (or anyone who encounters this issue) give me an example of your serverless.yml configuration and also your velocity template if any.

Believe that I have fixed this https://github.com/dherault/serverless-offline/pull/212

Let me know what you think :)

v3.10.3, let me know if it fixed it

This PR breaks the use of APIG's AWS_PROXY which requires the request body to be stringified and thus makes it incompatible with a deployed Lambda. So v3.10.3 breaks what worked fine in v3.10.2. 👎

Is it fixed by v3.11.0 ?

Yes, this works again with 3.11.0. Thanks 👍

My only worry is that, to my understanding, the PR #214 rolls back PR #212 and thus the original issue reported by @jagi, @imackinn and @em0ney (and others) might either still exist or happen again in 3.11.0. I never ran into the original issue in first place as I'm using Lambda Proxy.

Sorry for the late response. I only work on this project a few days a week and I was out last week for Spring break so please bear with me.

I upgraded to 3.11.0 but unfortunately it did not fix the issue. I'm not sure how to give you my setup without taking several hours to create a new project from scratch. I work on closed source code, unfortunately.

I'm just blindly stabbing in the dark here. The first thing my server side handler does is print out the event:

module.exports.addOrEdit = function(event, context, callback) {
  console.log("Event =" + JSON.stringify(event));

and that prints out:

Event ={"headers":{"Host":"localhost:3000","Connection":"keep-alive","Content-Length":327,"Accept":"*/*","Origin":"http://localhost:8080","User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36","Authorization":"eyJraWQiOiJyVlBOWE93WkgweTM3UmU5TzJ0MVg3ZWNucmowN2NrVEtuK1N6VTBJcUx3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJmOTk0YWMyOC1iMTE5LTQ2NzYtYmIzYi1hNjk5ZTM4YjZmMjEiLCJkZXZpY2Vfa2V5IjoidXMtZWFzdC0xXzE2ODNiOTViLWJlZmUtNGZhNS1hNzFkLWE5OTVkMjE2YTlkNCIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtZWFzdC0xLmFtYXpvbmF3cy5jb21cL3VzLWVhc3QtMV9HZlgySzVMSWoiLCJleHAiOjE0OTAwMjc5NTgsImlhdCI6MTQ5MDAyNDM1OCwianRpIjoiM2VhZjE1YTUtMmRiYi00MmNhLWFjMWUtZDY1N2UzNjcxNzVjIiwiY2xpZW50X2lkIjoiMXV0ZWM2aHB1OWkyNnY2M242NWVuYmVrcXQiLCJ1c2VybmFtZSI6InFkYnZpc2lvbi10ZXN0X19tYWlsaW5hdG9yLmNvbSJ9.P7hVfa-z99gbDVVvgRbq5XgU-q0_csASfyzgOdZJhDNlacBX_s7wPEFT4J2mIoThBIKX9FEik8Q0j4GI0Gtf5Y1TrfPxmGMRkLTYHVqwZZslr7ddrE-Mcdb3zQem0MMWd4oZ3gzXU82RHBU4rcDyG9Jtkiq3N6OLp1or5CYXGgIaCRYa_C4MpFRlJ5idOIpnYChTP-6MZGC9ngGoICDpYFBluu-zL4kYUQXHJFJNEYSKzbB3yNWalbHa70K-n79QKhKKSszPROvSNqUj8FiZ4BdcKxwdot2N6JHa9l2c_lgCWdyfKV63DOSTH9huoQ0S5YpU59tsyswgsOReZoog","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","Referer":"http://localhost:8080/users/viewEdit.html?operation=Edit&id=39","Accept-Encoding":"gzip, deflate, br","Accept-Language":"en-US,en;q=0.8"},"path":"/users/addOrEdit","pathParameters":null,"requestContext":{"accountId":"offlineContext_accountId","resourceId":"offlineContext_resourceId","stage":"dev","requestId":"offlineContext_requestId_","identity":{"cognitoIdentityPoolId":"offlineContext_cognitoIdentityPoolId","accountId":"offlineContext_accountId","cognitoIdentityId":"offlineContext_cognitoIdentityId","caller":"offlineContext_caller","apiKey":"offlineContext_apiKey","sourceIp":"127.0.0.1","cognitoAuthenticationType":"offlineContext_cognitoAuthenticationType","cognitoAuthenticationProvider":"offlineContext_cognitoAuthenticationProvider","userArn":"offlineContext_userArn","userAgent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36","user":"offlineContext_user"},"authorizer":{"principalId":"f994ac28-b119-4676-bb3b-a699e38b6f21"},"resourcePath":"/users/addOrEdit","httpMethod":"POST"},"resource":"/users/addOrEdit","httpMethod":"POST","queryStringParameters":null,"body":"{\"{\\\"enabled\\\":true,\\\"id\\\":39,\\\"firstName\\\":\\\"Ryan\\\",\\\"lastName\\\":\\\"Whatever\\\",\\\"email\\\":\\\"[email protected]\\\",\\\"group\\\":\\\"General\\\",\\\"title\\\":\\\"Asdf\\\",\\\"role\\\":\\\"Standard User\\\",\\\"lastLogin\\\":null,\\\"cognitoUUID\\\":null,\\\"createdAt\\\":\\\"2017-03-20T15:39:42.000Z\\\",\\\"updatedAt\\\":\\\"2017-03-20T15:39:42.000Z\\\",\\\"companyId\\\":30}\":\"\"}","stageVariables":null,"isOffline":true}

Maybe it's because I'm using a custom authorizer?

@rsshilli Maybe you are onto something. It may have to do with custom authorizer. Please @jagi @em0ney @arabold can you tell me what your setup is ?

  • Integration: proxy or not
  • Authorizer or not
  • Method: Post/get/...

So let's get this started:

  • Integration: Lambda Proxy
  • Authorizer: No
  • Method: ANY (but also POST, PUT and GET)

Expected behavior: Body should be a string.
Status: Works fine in 3.10.2 and 3.11.0 (the latest as of this writing). Broken in 3.10.3.

@arabold can you give us an example of what Chrome is sending (ex. is it JSON? Is it complicated in any way?) and what you receive in your handler in 3.11.0?

I'm reopenning.
Can you guys tell me if v3.13.1 fixed it ?

I will check it tomorrow and let you know

On Mon, Mar 27, 2017 at 3:12 PM, David Hérault notifications@github.com
wrote:

I'm reopenning.
Can you guys tell me if v3.13.1 fixed it ?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dherault/serverless-offline/issues/173#issuecomment-289448889,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABAKXXJuc_1qjeQlVvfUjYZOhg7tdu9Zks5rp7WogaJpZM4LMy2Z
.

@dherault works for me

@dherault v3.10.3 fixes it but it's broken in v3.11.0. The same is true for v3.12.0, v3.13.0 but v3.13.1 fixes it again. Is that expected?

No it's not. This package is 99% community maintained, I stopped coding new features one year ago. I tend to trust too much our contributors when I review PRs, that's why some issues come and go, and the code quality is quite low.
But on the other hand this plugin has more feature than any other, its essential complexity is not trivial.
I'll close this one, please ask to reopen it if necessary. :hammer_and_wrench:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ktwbc picture ktwbc  ·  4Comments

adambiggs picture adambiggs  ·  4Comments

stunningpixels picture stunningpixels  ·  3Comments

stonebraker picture stonebraker  ·  3Comments

Dong9769 picture Dong9769  ·  4Comments