'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