cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Aws lambda with Neo4jGraphQL Async Schema

joe5
Node Link

Hello friends.

I'm working with AWS Lambda using NodeJS. I had managed to create a GraphQL server with the Neo4J generated schema - that is until getting the schema turned into an Async function call.

My old code

import { ApolloServer } from 'apollo-server-lambda';
import { Neo4jGraphQL } from '@neo4j/graphql';

const neoSchema = new Neo4jGraphQL({
    typeDefs,
    driver: neo4j.getDriver,
    resolvers,
});

const apollo_server = new ApolloServer({
    schema: neoSchema.schema,
    introspection: process.env.SLS_STAGE === 'dev',
    context: ({ event, context, express }) => {
        console.log('event', event);
        return {
            headers: event.headers,
            functionName: context.functionName,
            event,
            context,
            expressRequest: express.req,
        };
    },
} as any);

export const graphqlHandler = apollo_server.createHandler();

This worked like a dream but (since upgrading) I can no longer access the schema with dot notation. I have to do something like const schema = await neoSchema.getSchema(). That's fine but because of the way Lambda's work and potentially my lack of knowledge if I put any kind of async await or promise in the way of the createHandler() on the apollo_server - the Lambda does not work and gives me a 502.

So I'm hoping someone cleverer than me has a workaround for this. For ref below are my package dependency versions

  "dependencies": {
    "@neo4j/graphql": "^3.1.0",
    "@neo4j/graphql-plugin-auth": "^1.0.0",
    "apollo-server-lambda": "^3.6.7",
    "aws-sdk": "^2.1067.0",
    "class-validator": "^0.13.2",
    "graphql": "^16.4.0",
    "lodash": "^4.17.21",
    "neo4j-driver": "^4.4.2",
    "reflect-metadata": "^0.1.13",
    "short-unique-id": "^4.4.4",
    "type-graphql": "^1.1.1",
    "uuid": "^8.3.2"
  },
1 ACCEPTED SOLUTION

joe5
Node Link

Turns out because I'd just done too many solutions and got bogged down thinking it was more complicated than it was. The solution is that you need to call the result of the createHandler function with the event,context,callback args from the exported function. Below is what I did and it works:-

const neoSchema = new Neo4jGraphQL({
    typeDefs,
    driver: neo4j.getDriver,
    resolvers,
});

const initServer = async () => {
    return await neoSchema.getSchema().then((schema) => {
        const server = new ApolloServer({
            schema,
            context: ({ event }) => ({ req: event }),
            introspection: process.env.SLS_STAGE === 'dev',
        });
        return server.createHandler();
    });
};

export const graphqlHandler = async (event, context, callback) => {
    const serverHandler = await initServer();

    return serverHandler(
            {
                ...event,
                requestContext: event.requestContext || {},
            },
            context,
            callback
    );
};

Hopefully this will assist someone else out there.

View solution in original post

1 REPLY 1

joe5
Node Link

Turns out because I'd just done too many solutions and got bogged down thinking it was more complicated than it was. The solution is that you need to call the result of the createHandler function with the event,context,callback args from the exported function. Below is what I did and it works:-

const neoSchema = new Neo4jGraphQL({
    typeDefs,
    driver: neo4j.getDriver,
    resolvers,
});

const initServer = async () => {
    return await neoSchema.getSchema().then((schema) => {
        const server = new ApolloServer({
            schema,
            context: ({ event }) => ({ req: event }),
            introspection: process.env.SLS_STAGE === 'dev',
        });
        return server.createHandler();
    });
};

export const graphqlHandler = async (event, context, callback) => {
    const serverHandler = await initServer();

    return serverHandler(
            {
                ...event,
                requestContext: event.requestContext || {},
            },
            context,
            callback
    );
};

Hopefully this will assist someone else out there.