Chirag atha
Chirag atha

Reputation: 47

Type 'Promise<GraphQLSchema>' is missing the following properties from type 'GraphQLSchema'

I am trying to launch an Apollo Server as a cloud function in typescript and want to use @cypher and @relationship directives in my typeDefs.

To use these directives I am using "@neo4j/graphql": "^3.0.0".

I am getting errors while providing schema to the apollo server. getSchema() returns a Promise but ApollServer expects a schema of type GraphQL Schema.

const neoSchema = new Neo4jGraphQL({ typeDefs });

const server = new ApolloServer({
  schema: neoSchema.getSchema(),
  context: ({ req }) => ({
    headers: req.headers,
    req,
  }),
});

exports.handler = server.createHandler();

Would really appreciate it if someone can help me out here.

Upvotes: 0

Views: 904

Answers (1)

Dan Crews
Dan Crews

Reputation: 3607

Apollo Server can't handle a promise at this step, and you can't do top-level awaits (unless you're on typescript.next), so you have to wrap this in another function.

DANGER: DON'T SKIP THIS BIT

If you don't memoize this, you'll create a new handler on every invocation, which opens you up to a file descriptor leak. The symptom of this is that you'll start getting timeouts for EVERYTHING (including DNS lookups), so you'll start getting ENOTFOUND errors in your code. I've added a comment for your future generations:


const neoSchema = new Neo4jGraphQL({ typeDefs });
let _cachedHandler: ReturnType<ApolloServer['createHandler']>;

/**
 * We have to be careful here that we're not creating a new server on EVERY invocation
 * because that will create a file descriptor leak. Make sure you're using a memoized cache
 */
const memoizedHandler = async (event, context) => {
  if (!_cachedHandler) {
    const server = new ApolloServer({
      schema: await neoSchema.getSchema(),
      context: ({ req }) => ({
        headers: req.headers,
        req,
      }),
    });
    // this is the actual handler
    _cachedHandler = server.createHandler();
  }
  // now we can just call the handler
  return _cachedHandler(event, context);
}

exports.handler = memoizedHandler;

Upvotes: 2

Related Questions