How to use node8.10 with GraphQL and async/await

I’m trying to upgrade to node 8.10, but my function stops working. I see errors like:

Serverless: Warning: handler 'graphql' returned a promise and also use a callback!
This is problematic and might cause issues in you lambda.

Serverless: Warning: context.done called twice within handler 'graphql'!

Here’s what my handler looks like:

exports.handler = async (event: any, serverlessContext: lambda.Context, callback: any) => {
    Logger.info(`************************************** START GRAPHQL FUNCTION **************************************`)
    // This enables Lambda function to complete
    serverlessContext.callbackWaitsForEmptyEventLoop = false

    // This is to prevent building schema twice
    // tslint:disable-next-line:align
    ;(global as any).schema =
        (global as any).schema ||
        (await TypeGraphQL.buildSchema({
            resolvers: [AmenityResolver, AuthResolver, HotelResolver, LocationResolver, UserResolver]
        }))
    const schema = (global as any).schema

    await setupContainer()

    // In order to prevent a circular dependency, we need to pass the User repo in here so that we can
    // add the appropriate user to the context, which we then pass to all other services
    // in addServicesToContainer()
    const context = await setupContext(event, serverlessContext, dbConn.getRepository(User))

    // Sending in copy of context so none of the below code fucks with it in the service layer
    addServicesToContainer(Object.assign({}, context))

    const apolloServerConfig: Config = {
        schema,
        context
    }

    Logger.info(`Initializing ApolloServer ...`)
    const apolloServer = new ApolloServer(apolloServerConfig)

    Logger.info(`Creating handler ...`)
    const handler = apolloServer.createHandler({
        cors: {
            origin: '*',
            credentials: true
        }
    })

    return handler(event, serverlessContext, callback)
}

Any help much appreciated!

For node 8.10 there are two supported syntax for the handler:

async (event: any, serverlessContext: lambda.Context)

and

(event: any, serverlessContext: lambda.Context, callback: any)

You’re trying to mix the two by declaring the function async and then using callback which isn’t supported. I wrote a post about node 8.10 handlers if you want more detail.

Thanks Buggy! Your approach works in general and thanks for pointing me to your post about node 8.10 handlers. What it doesn’t account for, specifically, is the Apollo graphql handler, which requires a callback. Any thoughts on how to handle that?

You can still use callback’s if you don’t declare the handler async.

Yea, thanks, would love to have a clean approach that only uses async/await, but I guess I’ll have to “wait”. :wink: