question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

'POST body missing' when programmatically invoking graphql handler in v3

See original GitHub issue

When I programmatically invoke the graphql handler of the example posted by @Alec2435 in #5462, I get the following error:

{
    "body": "POST body missing, invalid Content-Type, or JSON object has no keys.", 
    "isBase64Encoded": false, 
    "multiValueHeaders":  {
        "access-control-allow-origin": ["*"], 
        "content-length": ["68"], 
        "content-type": ["text/html; charset=utf-8"], 
        "etag": ["W/\"44-LstwwwiSrcEeuZb+mu4TKVPIfxQ\""], 
        "x-powered-by": ["Express"]
    },
    "statusCode": 400
}
  • The package name and version of Apollo showing the problem.

I’m using “apollo-server-lambda” version 3.0.1.

  • The expected behavior.

That it executes as in v2.

  • The actual behavior.

It returns the message “POST body missing, invalid Content-Type, or JSON object has no keys.”.

  • A simple, runnable reproduction!

I’m executing this code:

   const event  = generateEvent({
            query: `
              query {
                hello
              }
            `,
        });
    const result = await graphqlHandler(event, {});
    expect(result.body).toEqual("{\"data\":{\"hello\":\"Hello world!\"}}\n");

Where the event is generated by:


exports.generateEvent = body => ({
    body: body ? JSON.stringify(body) : null,
    headers: {
        "Accept": "application/json",
        "Content-Type": "application/json",
    },
    multiValueHeaders: {},
    httpMethod: "POST",
    isBase64Encoded: false,
    path: "/",
    pathParameters: null,
    queryStringParameters: null,
    multiValueQueryStringParameters: null,
    stageVariables: null,
    requestContext: {
        accountId: "1234567890",
        apiId: "appid",
        httpMethod: "POST",
        identity: {},
        authorizer: {},
        protocol: "HTTP/1.1",
        path: "/",
        stage: "dev",
        requestId: "test",
        requestTimeEpoch: 0,
        resourceId: "none",
        resourcePath: "/",
    },
    resource: "/",
});

Is it a bug or am I doing something wrong? In v2 it works perfectly!

_Originally posted by @tiagocpeixoto in https://github.com/apollographql/apollo-server/issues/5462#issuecomment-881956725_

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
tiagocpeixotocommented, Jul 20, 2021

Okay, finally got it after @glasser’s mention about the body-parser. I analyzed the example I prepared and I found that the fake ApiGatewaryEvent shouldn’t have the multiValueHeaders property set (it should be be null or undefined), because of this @vendia/serverless-express code:

  if (event.multiValueHeaders) {
    headers = getCommaDelimitedHeaders({ headersMap: event.multiValueHeaders, lowerCaseKey: true })
  } else {
    headers = event.headers
  }

The problem is that the APIGatewayEvent type of the “aws-lambda” package makes it mandatory, which led me to the error (I’m using Typescript in my project, althought I haven’t used it in this example).

Another approach is to add the Content-Type header to the multiValueHeaders property, which also solves the problem:

exports.generateEvent = body => ({
    body: body ? JSON.stringify(body) : null,
    headers: {
        "Accept": "application/json",
        // "content-type": "application/json", // <-- COMMENT THIS...
    },
    multiValueHeaders: {
        "content-type": "application/json",  // <-- ...AND ADD THIS
    },
    httpMethod: "POST",
    isBase64Encoded: false,
    path: "/",
    pathParameters: null,
    queryStringParameters: null,
    multiValueQueryStringParameters: null,
    stageVariables: null,
    requestContext: {
        accountId: "1234567890",
        apiId: "appid",
        httpMethod: "POST",
        identity: {},
        authorizer: {},
        protocol: "HTTP/1.1",
        path: "/",
        stage: "dev",
        requestId: "test",
        requestTimeEpoch: 0,
        resourceId: "none",
        resourcePath: "/",
    },
    resource: "/",
});

Finally, it is noteworthy that this behavior did not occur with v2. Should it be explained in the migration guide?

1reaction
tiagocpeixotocommented, Jul 20, 2021

Ok, I made an example for reproduction located at https://github.com/tiagocpeixoto/apollo-serverless-bug based on the example from @Alec2435.

This version uses apollo-server-lambda v2. If you change it to version 3.0.1, it won’t work.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Full Stack Error Handling with GraphQL and Apollo
Request Errors occur when the client is at fault. There are 3 phases to a GraphQL query and client-caused errors may occur in...
Read more >
node.js - GraphQL - POST body missing. Did you forget use ...
I got it with apollo-server-micro inside a custom api route of NextJs. It can be fixed by calling the json function coming from...
Read more >
GraphQL vs. REST APIs: Why you shouldn't use GraphQL
We'll discuss the drawbacks of using GraphQL, including performance issues, problems with GraphQL schemas, and complex queries.
Read more >
Build a GraphQL Server with Spring Boot | Pluralsight
Learn how to build a GraphQL server that will expose an API to create, update and delete entities of type Book with attributes...
Read more >
Table of Contents - Micronaut Documentation
3.0 support GraalVM 22.1.0. Incremental Compilation for Gradle Builds. Micronaut framework 3.5 supports fully incremental compilation, including GraalVM ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found