graphqlserverless-frameworkapollo-serverserverless-offline

Attempting to use apollo-server's playground results in Unexpected end of JSON input


I'm getting this error when I launch the playground in my apolly-server-lambda application:

Playground.tsx:289 SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at index.js:40

The app has only one test resolver. I use type-graphql to define the schema:

@Resolver()
export class InviteResolver {

    @Query(() => String)
    hello() {
        return 'test';
    }

}

And then I configured the apollo server with the generated schema:

async function createHandler() {
    const schema = await buildSchema({
        resolvers: [InviteResolver]
    });

    const server = new ApolloServer({
        schema,
        playground: {
            endpoint: "/dev/graphql"
        }
    })

    return server.createHandler({
        cors: {
            origin: '*',
            methods: '*',
            allowedHeaders: '*',
            credentials: true,
        },
    });
}

export const handler = async function(event: APIGatewayProxyEvent, context: LambdaContext, callback: APIGatewayProxyCallback) {
    context.callbackWaitsForEmptyEventLoop = false;
    return await createHandler()
        .then(handler => handler(event, context, callback));
};

Finally, I have it all set with serverless:

service: app
provider:
  name: aws
  runtime: nodejs12.x
  region: us-east-1
  apiGateway:
    shouldStartNameWithService: true
functions:
  graphql:
    handler: src/app.handler
    events:
      - http:
          path: /graphql
          method: post
          cors: true
      - http:
          path: /graphql
          method: get
          cors: true
plugins:
  - serverless-dotenv-plugin
  - serverless-plugin-typescript
  - serverless-offline

As you can see in the configs I use serverless-offline to develop, and I start things with:

serverless offline start

And it seems to start successfully:

   ┌───────────────────────────────────────────────────────────────────────────┐
   │                                                                           │
   │   POST | http://localhost:3000/dev/graphql                                │
   │   POST | http://localhost:3000/2015-03-31/functions/graphql/invocations   │
   │   GET  | http://localhost:3000/dev/graphql                                │
   │   POST | http://localhost:3000/2015-03-31/functions/graphql/invocations   │
   │                                                                           │
   └───────────────────────────────────────────────────────────────────────────┘

I can access the playground UI at http://localhost:3000/dev/graphql, but immediately I start seeing the error above in the console over and over. I can't see the schema or doc tabs (essentially all polling fails), and no query reaches that resolver.

Do you guys see anything wrong in how I wired things?


Solution

  • The issue was that I was exporting an async function instead of a regular one.

    What worked for me was:

    const globalSchema = buildSchema({
        resolvers: [InviteResolver]
    });
    
    async function getServer() {
        const schema = await globalSchema;
        return new ApolloServer({
            schema,
            playground: {
                endpoint: "/dev/graphql"
            }
        });
    }
    
    export function handler(event: any, ctx: any, callback: any) {
        getServer()
            .then(server => server.createHandler({
                cors: {
                    origin: '*',
                    methods: '*',
                    allowedHeaders: '*',
                    credentials: true,
                },
            }))
            .then(handler => handler(event, ctx, callback))
    }